From afe39f259042a5a6dfa558d4b96b214b84be5926 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Oct 2004 22:27:19 +0200 Subject: Optimization: in the replication slave, we can avoid doing one strlen() per event's execution, as we already have db_len in Log_event. Only if rewrite_db() changed the db we need a strlen (so we now do the strlen() in rewrite_db). Plus a test (we had none for --replicate-rewrite-db :( ). sql/log_event.cc: The goal is to get of rid of one strlen() per replication event in slave: we don't need to compute strlen(thd->db) as we already have db_len in the event; only case where we need to do a strlen() is if rewrite_db() changed the db. Note that db_len is always a meaningful value. It's 0 if event's db is 0. sql/slave.cc: rewrite_db now returns the len of the returned db. print_slave_db_safe() needn't call rewrite_db() as rewrite_db() is already called by caller. sql/slave.h: declaration updates for slave.cc --- sql/log_event.cc | 23 ++++++++++------------- sql/slave.cc | 7 +++++-- sql/slave.h | 4 ++-- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'sql') diff --git a/sql/log_event.cc b/sql/log_event.cc index 326f2fc5c59..977c3c0fe24 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -977,7 +977,8 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) int Query_log_event::exec_event(struct st_relay_log_info* rli) { int expected_error,actual_error= 0; - thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed + thd->db_length= db_len; + thd->db= (char*) rewrite_db(db, &thd->db_length); /* InnoDB internally stores the master log position it has processed so far; @@ -995,11 +996,6 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); - /* - We cannot use db_len from event to fill thd->db_length, because - rewrite_db() may have changed db. - */ - thd->db_length= thd->db ? strlen(thd->db) : 0; thd->query_length= q_len; thd->query = (char*)query; VOID(pthread_mutex_lock(&LOCK_thread_count)); @@ -1057,7 +1053,7 @@ Default database: '%s'. Query: '%s'", expected_error, actual_error ? thd->net.last_error: "no error", actual_error, - print_slave_db_safe(db), query); + print_slave_db_safe(thd->db), query); thd->query_error= 1; } /* @@ -1078,7 +1074,7 @@ Default database: '%s'. Query: '%s'", "Error '%s' on query. Default database: '%s'. Query: '%s'", (actual_error ? thd->net.last_error : "unexpected success or fatal error"), - print_slave_db_safe(db), query); + print_slave_db_safe(thd->db), query); thd->query_error= 1; } } /* End of if (db_ok(... */ @@ -1706,7 +1702,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, bool use_rli_only_for_errors) { char *load_data_query= 0; - thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed + thd->db_length= db_len; + thd->db= (char*) rewrite_db(db, &thd->db_length); DBUG_ASSERT(thd->query == 0); thd->query_length= 0; // Should not be needed thd->query_error= 0; @@ -1741,7 +1738,6 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); - thd->db_length= thd->db ? strlen(thd->db) : 0; VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); @@ -1847,7 +1843,7 @@ Slave: load data infile on table '%s' at log position %s in log \ (char*) table_name, llstr(log_pos,llbuff), RPL_LOG_NAME, (ulong) thd->cuted_fields, - print_slave_db_safe(db)); + print_slave_db_safe(thd->db)); } if (net) net->pkt_nr= thd->net.pkt_nr; @@ -1865,6 +1861,7 @@ Slave: load data infile on table '%s' at log position %s in log \ } thd->net.vio = 0; + char *save_db= thd->db; VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db= 0; thd->query= 0; @@ -1887,7 +1884,7 @@ Slave: load data infile on table '%s' at log position %s in log \ } slave_print_error(rli,sql_errno,"\ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", - err, (char*)table_name, print_slave_db_safe(db)); + err, (char*)table_name, print_slave_db_safe(save_db)); free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); return 1; } @@ -1897,7 +1894,7 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'", { slave_print_error(rli,ER_UNKNOWN_ERROR, "\ Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'", - (char*)table_name, print_slave_db_safe(db)); + (char*)table_name, print_slave_db_safe(save_db)); return 1; } diff --git a/sql/slave.cc b/sql/slave.cc index 4ef8715f1e6..d5278e06d8a 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1032,7 +1032,7 @@ bool net_request_file(NET* net, const char* fname) } -const char *rewrite_db(const char* db) +const char *rewrite_db(const char* db, uint *new_len) { if (replicate_rewrite_db.is_empty() || !db) return db; @@ -1042,7 +1042,10 @@ const char *rewrite_db(const char* db) while ((tmp=it++)) { if (!strcmp(tmp->key, db)) + { + *new_len= strlen(tmp->val); return tmp->val; + } } return db; } @@ -1056,7 +1059,7 @@ const char *rewrite_db(const char* db) const char *print_slave_db_safe(const char* db) { - return (db ? rewrite_db(db) : ""); + return (db ? db : ""); } /* diff --git a/sql/slave.h b/sql/slave.h index 20167094453..97f197fb50a 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -510,8 +510,8 @@ int add_table_rule(HASH* h, const char* table_spec); int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec); void init_table_rule_hash(HASH* h, bool* h_inited); void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited); -const char *rewrite_db(const char* db); -const char *print_slave_db_safe(const char* db); +const char *rewrite_db(const char* db, uint *new_db_len); +const char *print_slave_db_safe(const char *db); int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code); void skip_load_data_infile(NET* net); void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...); -- cgit v1.2.1 From 066c90563a9fd6151461a5d54d879079acffe279 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Oct 2004 04:04:37 +0300 Subject: errors without code removed net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed (WL#2133) include/mysqld_error.h: new errors added. mysql-test/r/rpl_charset.result: new error mysql-test/r/rpl_timezone.result: new error mysql-test/r/sp-security.result: more clean error message mysql-test/r/sp.result: now error state intercepted correctly mysql-test/t/connect.test: new error message mysql-test/t/rpl_charset.test: new error message mysql-test/t/rpl_timezone.test: new error mysql-test/t/sp-security.test: more correct error handling mysql-test/t/sp.test: now error state intercepted correctly sql/ha_innodb.cc: -1/1 (sent/unsent) error reporting removed sql/ha_innodb.h: -1/1 (sent/unsent) error reporting removed sql/item.cc: only boolean values should be returned by fix_fields() sql/item_cmpfunc.cc: only boolean values should be returned by fix_fields() sql/item_func.cc: only boolean values should be returned by fix_fields() net_printf/send_error calls replaced by my_error family functions sql/item_row.cc: only boolean values should be returned by fix_fields() sql/item_subselect.cc: only boolean values should be returned by fix_fields() -1/1 (sent/unsent) error reporting removed sql/item_subselect.h: -1/1 (sent/unsent) error reporting removed sql/item_sum.cc: only boolean values should be returned by fix_fields() sql/item_timefunc.cc: only boolean values should be returned by fix_fields() sql/item_uniq.h: only boolean values should be returned by fix_fields() sql/mysql_priv.h: -1/1 (sent/unsent) error reporting removed sql/mysqld.cc: net_printf/send_error calls replaced by my_error family functions changes in my_message_sql to support error handling correctly sql/protocol.cc: net_printf/send_error calls replaced by my_error family functions sql/protocol_cursor.cc: net_printf/send_error calls replaced by my_error family functions sql/repl_failsafe.cc: net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed sql/repl_failsafe.h: -1/1 (sent/unsent) error reporting removed sql/set_var.cc: net_printf/send_error calls replaced by my_error family functions sql/share/czech/errmsg.txt: new error messages sql/share/danish/errmsg.txt: new error messages sql/share/dutch/errmsg.txt: new error messages sql/share/english/errmsg.txt: new error messages sql/share/estonian/errmsg.txt: new error messages sql/share/french/errmsg.txt: new error messages sql/share/german/errmsg.txt: new error messages sql/share/greek/errmsg.txt: new error messages sql/share/hungarian/errmsg.txt: new error messages sql/share/italian/errmsg.txt: new error messages sql/share/japanese/errmsg.txt: new error messages sql/share/korean/errmsg.txt: new error messages sql/share/norwegian-ny/errmsg.txt: new error messages sql/share/norwegian/errmsg.txt: new error messages sql/share/polish/errmsg.txt: new error messages sql/share/portuguese/errmsg.txt: new error messages sql/share/romanian/errmsg.txt: new error messages sql/share/russian/errmsg.txt: new error messages sql/share/serbian/errmsg.txt: new error messages sql/share/slovak/errmsg.txt: new error messages sql/share/spanish/errmsg.txt: new error messages sql/share/swedish/errmsg.txt: new error messages sql/share/ukrainian/errmsg.txt: new error messages sql/slave.cc: net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed sql/slave.h: -1/1 (sent/unsent) error reporting removed sql/sp.cc: net_printf/send_error calls replaced by my_error family functions sql/sp_head.cc: new eror handling support net_printf/send_error calls replaced by my_error family functions sql/sp_rcontext.cc: net_printf/send_error calls replaced by my_error family functions sql/sql_acl.cc: net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed sql/sql_acl.h: -1/1 (sent/unsent) error reporting removed sql/sql_base.cc: -1/1 (sent/unsent) error reporting removed net_printf/send_error calls replaced by my_error family functions sql/sql_class.cc: net_printf/send_error calls replaced by my_error family functions sql/sql_class.h: my_messhage_sql now set/reset query_error flag sql/sql_db.cc: -1/1 (sent/unsent) error reporting removed sql/sql_delete.cc: -1/1 (sent/unsent) error reporting removed net_printf/send_error calls replaced by my_error family functions sql/sql_do.cc: -1/1 (sent/unsent) error reporting removed sql/sql_error.cc: -1/1 (sent/unsent) error reporting removed sql/sql_handler.cc: -1/1 (sent/unsent) error reporting removed net_printf/send_error calls replaced by my_error family functions sql/sql_help.cc: net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed sql/sql_insert.cc: -1/1 (sent/unsent) error reporting removed net_printf/send_error calls replaced by my_error family functions sql/sql_lex.h: -1/1 (sent/unsent) error reporting removed sql/sql_load.cc: -1/1 (sent/unsent) error reporting removed sql/sql_map.cc: errors without code removed sql/sql_parse.cc: net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed from mysql_execute_command sql/sql_prepare.cc: net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed sql/sql_repl.cc: error messages fixed net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed sql/sql_repl.h: -1/1 (sent/unsent) error reporting removed sql/sql_select.cc: -1/1 (sent/unsent) error reporting removed sql/sql_select.h: -1/1 (sent/unsent) error reporting removed sql/sql_show.cc: -1/1 (sent/unsent) error reporting removed net_printf/send_error calls replaced by my_error family functions sql/sql_table.cc: net_printf/send_error calls replaced by my_error family functions -1/1 (sent/unsent) error reporting removed sql/sql_trigger.cc: -1/1 (sent/unsent) error reporting removed sql/sql_udf.cc: net_printf/send_error calls replaced by my_error family functions sql/sql_union.cc: -1/1 (sent/unsent) error reporting removed sql/sql_update.cc: -1/1 (sent/unsent) error reporting removed net_printf/send_error calls replaced by my_error family functions sql/sql_view.cc: -1/1 (sent/unsent) error reporting removed sql/sql_view.h: -1/1 (sent/unsent) error reporting removed sql/sql_yacc.yy: net_printf/send_error calls replaced by my_error family functions --- sql/ha_innodb.cc | 12 +- sql/ha_innodb.h | 2 +- sql/item.cc | 66 ++--- sql/item_cmpfunc.cc | 32 +-- sql/item_func.cc | 44 +-- sql/item_row.cc | 4 +- sql/item_subselect.cc | 35 +-- sql/item_subselect.h | 8 +- sql/item_sum.cc | 26 +- sql/item_timefunc.cc | 4 +- sql/item_uniq.h | 2 +- sql/mysql_priv.h | 238 ++++++++--------- sql/mysqld.cc | 20 +- sql/protocol.cc | 5 +- sql/protocol_cursor.cc | 2 +- sql/repl_failsafe.cc | 49 ++-- sql/repl_failsafe.h | 6 +- sql/set_var.cc | 22 +- sql/share/czech/errmsg.txt | 19 ++ sql/share/danish/errmsg.txt | 19 ++ sql/share/dutch/errmsg.txt | 19 ++ sql/share/english/errmsg.txt | 19 ++ sql/share/estonian/errmsg.txt | 19 ++ sql/share/french/errmsg.txt | 19 ++ sql/share/german/errmsg.txt | 19 ++ sql/share/greek/errmsg.txt | 19 ++ sql/share/hungarian/errmsg.txt | 19 ++ sql/share/italian/errmsg.txt | 19 ++ sql/share/japanese/errmsg.txt | 19 ++ sql/share/korean/errmsg.txt | 19 ++ sql/share/norwegian-ny/errmsg.txt | 19 ++ sql/share/norwegian/errmsg.txt | 19 ++ sql/share/polish/errmsg.txt | 19 ++ sql/share/portuguese/errmsg.txt | 19 ++ sql/share/romanian/errmsg.txt | 19 ++ sql/share/russian/errmsg.txt | 19 ++ sql/share/serbian/errmsg.txt | 19 ++ sql/share/slovak/errmsg.txt | 19 ++ sql/share/spanish/errmsg.txt | 19 ++ sql/share/swedish/errmsg.txt | 19 ++ sql/share/ukrainian/errmsg.txt | 19 ++ sql/slave.cc | 25 +- sql/slave.h | 4 +- sql/sp.cc | 2 +- sql/sp_head.cc | 21 +- sql/sp_rcontext.cc | 12 +- sql/sql_acl.cc | 90 +++---- sql/sql_acl.h | 16 +- sql/sql_base.cc | 20 +- sql/sql_class.cc | 4 +- sql/sql_class.h | 1 + sql/sql_db.cc | 32 +-- sql/sql_delete.cc | 81 +++--- sql/sql_do.cc | 6 +- sql/sql_error.cc | 14 +- sql/sql_handler.cc | 43 ++- sql/sql_help.cc | 68 ++--- sql/sql_insert.cc | 68 +++-- sql/sql_lex.h | 10 +- sql/sql_load.cc | 26 +- sql/sql_map.cc | 8 +- sql/sql_parse.cc | 550 +++++++++++++++++--------------------- sql/sql_prepare.cc | 209 ++++++--------- sql/sql_repl.cc | 91 +++---- sql/sql_repl.h | 10 +- sql/sql_select.cc | 56 ++-- sql/sql_select.h | 2 +- sql/sql_show.cc | 200 +++++++------- sql/sql_table.cc | 180 ++++++------- sql/sql_trigger.cc | 25 +- sql/sql_udf.cc | 21 +- sql/sql_union.cc | 70 +++-- sql/sql_update.cc | 101 ++++--- sql/sql_view.cc | 52 ++-- sql/sql_view.h | 6 +- sql/sql_yacc.yy | 236 ++++++++-------- 76 files changed, 1825 insertions(+), 1549 deletions(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4d068cfc0ce..7c911ca60bd 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4821,7 +4821,7 @@ ha_innobase::external_lock( Implements the SHOW INNODB STATUS command. Sends the output of the InnoDB Monitor to the client. */ -int +bool innodb_show_status( /*===============*/ THD* thd) /* in: the MySQL query thread of the caller */ @@ -4835,7 +4835,7 @@ innodb_show_status( my_message(ER_NOT_SUPPORTED_YET, "Cannot call SHOW INNODB STATUS because skip-innodb is defined", MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } trx = check_trx_exists(thd); @@ -4864,7 +4864,7 @@ innodb_show_status( if (!(str = my_malloc(flen + 1, MYF(0)))) { mutex_exit_noninline(&srv_monitor_file_mutex); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } rewind(srv_monitor_file); @@ -4881,7 +4881,7 @@ innodb_show_status( my_free(str, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } protocol->prepare_for_resend(); @@ -4889,10 +4889,10 @@ innodb_show_status( my_free(str, MYF(0)); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /**************************************************************************** diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index fa3e9f012e8..a2017d59cc3 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -222,7 +222,7 @@ int innobase_savepoint( my_off_t binlog_cache_pos); int innobase_close_connection(THD *thd); int innobase_drop_database(char *path); -int innodb_show_status(THD* thd); +bool innodb_show_status(THD* thd); my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name, uint full_name_len); diff --git a/sql/item.cc b/sql/item.cc index 267560b0709..813eaf41b45 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1279,7 +1279,7 @@ bool Item::fix_fields(THD *thd, // We do not check fields which are fixed during construction DBUG_ASSERT(fixed == 0 || basic_const_item()); fixed= 1; - return 0; + return FALSE; } double Item_ref_null_helper::val() @@ -1447,9 +1447,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } } if (!tmp) - return -1; + return TRUE; if (!refer) - return 1; + return TRUE; if (tmp == not_found_field && refer == (Item **)not_found_item) { if (upward_lookup) @@ -1463,7 +1463,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) // Call to report error find_field_in_tables(thd, this, tables, ref, 1, 1); } - return -1; + return TRUE; } else if (refer != (Item **)not_found_item) { @@ -1471,7 +1471,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, "forward reference in item list"); - return -1; + return TRUE; } Item_ref *rf; @@ -1481,16 +1481,16 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) (char *)field_name); register_item_tree_changing(ref); if (!rf) - return 1; + return TRUE; /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() */ if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1)) - return 1; + return TRUE; mark_as_dependent(thd, last, cursel, rf); - return 0; + return FALSE; } else { @@ -1503,7 +1503,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) (char *)cached_table->alias, (char *)field_name); if (!rf) - return 1; + return TRUE; /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() @@ -1513,7 +1513,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } } else if (!tmp) - return -1; + return TRUE; /* if it is not expression from merged VIEW we will set this field. @@ -1564,12 +1564,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) thd->host_or_ip, field_name, tab); - return 1; + return TRUE; } } #endif fixed= 1; - return 0; + return FALSE; } void Item_field::cleanup() @@ -2209,9 +2209,9 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } if (!ref) - return 1; + return TRUE; else if (!tmp) - return -1; + return TRUE; else if (ref == (Item **)not_found_item && tmp == not_found_field) { if (upward_lookup) @@ -2229,7 +2229,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) REPORT_ALL_ERRORS); } ref= 0; - return 1; + return TRUE; } else if (tmp != not_found_field) { @@ -2238,10 +2238,10 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { Item_field* fld; if (!((*reference)= fld= new Item_field(tmp))) - return 1; + return TRUE; mark_as_dependent(thd, last, thd->lex->current_select, fld); register_item_tree_changing(reference); - return 0; + return FALSE; } /* We can leave expression substituted from view for next PS/SP @@ -2261,7 +2261,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, "forward reference in item list"); - return -1; + return TRUE; } mark_as_dependent(thd, last, thd->lex->current_select, this); @@ -2269,14 +2269,14 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } } else if (!ref) - return 1; + return TRUE; else { if (!(*ref)->fixed) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, "forward reference in item list"); - return -1; + return TRUE; } ref= thd->lex->current_select->ref_pointer_array + counter; } @@ -2299,7 +2299,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) ((*ref)->with_sum_func? "reference on group function": "forward reference in item list")); - return 1; + return TRUE; } max_length= (*ref)->max_length; maybe_null= (*ref)->maybe_null; @@ -2309,8 +2309,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) fixed= 1; if (ref && (*ref)->check_cols(1)) - return 1; - return 0; + return TRUE; + return FALSE; } @@ -2416,17 +2416,17 @@ bool Item_default_value::fix_fields(THD *thd, if (!arg) { fixed= 1; - return 0; + return FALSE; } if (arg->fix_fields(thd, table_list, &arg)) - return 1; + return TRUE; if (arg->type() == REF_ITEM) { Item_ref *ref= (Item_ref *)arg; if (ref->ref[0]->type() != FIELD_ITEM) { - return 1; + return TRUE; } arg= ref->ref[0]; } @@ -2435,16 +2435,16 @@ bool Item_default_value::fix_fields(THD *thd, { my_printf_error(ER_NO_DEFAULT_FOR_FIELD, ER(ER_NO_DEFAULT_FOR_FIELD), MYF(0), field_arg->field->field_name); - return 1; + return TRUE; } if (!(def_field= (Field*) sql_alloc(field_arg->field->size_of()))) - return 1; + return TRUE; memcpy(def_field, field_arg->field, field_arg->field->size_of()); def_field->move_field(def_field->table->default_values - def_field->table->record[0]); set_field(def_field); fixed= 1; - return 0; + return FALSE; } void Item_default_value::print(String *str) @@ -2472,14 +2472,14 @@ bool Item_insert_value::fix_fields(THD *thd, { DBUG_ASSERT(fixed == 0); if (arg->fix_fields(thd, table_list, &arg)) - return 1; + return TRUE; if (arg->type() == REF_ITEM) { Item_ref *ref= (Item_ref *)arg; if (ref->ref[0]->type() != FIELD_ITEM) { - return 1; + return TRUE; } arg= ref->ref[0]; } @@ -2488,7 +2488,7 @@ bool Item_insert_value::fix_fields(THD *thd, { Field *def_field= (Field*) sql_alloc(field_arg->field->size_of()); if (!def_field) - return 1; + return TRUE; memcpy(def_field, field_arg->field, field_arg->field->size_of()); def_field->move_field(def_field->table->insert_values - def_field->table->record[0]); @@ -2502,7 +2502,7 @@ bool Item_insert_value::fix_fields(THD *thd, tmp_field->table, &my_charset_bin)); } fixed= 1; - return 0; + return FALSE; } void Item_insert_value::print(String *str) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 582277cd142..252c6d29f5e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -631,17 +631,17 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables, { DBUG_ASSERT(fixed == 0); if (fix_left(thd, tables, ref)) - return 1; + return TRUE; if (args[0]->maybe_null) maybe_null=1; if (!args[1]->fixed && args[1]->fix_fields(thd, tables, args+1)) - return 1; + return TRUE; Item_in_subselect * sub= (Item_in_subselect *)args[1]; if (args[0]->cols() != sub->engine->cols()) { my_error(ER_OPERAND_COLUMNS, MYF(0), args[0]->cols()); - return 1; + return TRUE; } if (args[1]->maybe_null) maybe_null=1; @@ -650,7 +650,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, struct st_table_list *tables, not_null_tables_cache|= args[1]->not_null_tables(); const_item_cache&= args[1]->const_item(); fixed= 1; - return 0; + return FALSE; } @@ -1964,7 +1964,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) and_tables_cache= ~(table_map) 0; if (check_stack_overrun(thd, buff)) - return 1; // Fatal error flag is set! + return TRUE; // Fatal error flag is set! while ((item=li++)) { table_map tmp_table_map; @@ -1982,7 +1982,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if ((!item->fixed && item->fix_fields(thd, tables, li.ref())) || (item= *li.ref())->check_cols(1)) - return 1; /* purecov: inspected */ + return TRUE; /* purecov: inspected */ used_tables_cache|= item->used_tables(); tmp_table_map= item->not_null_tables(); not_null_tables_cache|= tmp_table_map; @@ -1995,7 +1995,7 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) thd->lex->current_select->cond_count+= list.elements; fix_length_and_dec(); fixed= 1; - return 0; + return FALSE; } bool Item_cond::walk(Item_processor processor, byte *arg) @@ -2306,12 +2306,12 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) DBUG_ASSERT(fixed == 0); if (Item_bool_func2::fix_fields(thd, tlist, ref) || escape_item->fix_fields(thd, tlist, &escape_item)) - return 1; + return TRUE; if (!escape_item->const_during_execution()) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"ESCAPE"); - return 1; + return TRUE; } if (escape_item->const_item()) @@ -2329,7 +2329,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) { String* res2 = args[1]->val_str(&tmp_value2); if (!res2) - return 0; // Null argument + return FALSE; // Null argument const size_t len = res2->length(); const char* first = res2->ptr(); @@ -2362,7 +2362,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) } } } - return 0; + return FALSE; } #ifdef USE_REGEX @@ -2373,13 +2373,13 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) DBUG_ASSERT(fixed == 0); if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1) || args[1]->fix_fields(thd,tables, args + 1) || args[1]->check_cols(1)) - return 1; /* purecov: inspected */ + return TRUE; /* purecov: inspected */ with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; max_length= 1; decimals= 0; if (agg_arg_collations(cmp_collation, args, 2)) - return 1; + return TRUE; used_tables_cache=args[0]->used_tables() | args[1]->used_tables(); not_null_tables_cache= (args[0]->not_null_tables() | @@ -2393,7 +2393,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (args[1]->null_value) { // Will always return NULL maybe_null=1; - return 0; + return FALSE; } int error; if ((error=regcomp(&preg,res->c_ptr(), @@ -2404,7 +2404,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { (void) regerror(error,&preg,buff,sizeof(buff)); my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff); - return 1; + return TRUE; } regex_compiled=regex_is_const=1; maybe_null=args[0]->maybe_null; @@ -2412,7 +2412,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) else maybe_null=1; fixed= 1; - return 0; + return FALSE; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 4aec7fea2d4..38f0d514314 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -199,8 +199,8 @@ Item_func::Item_func(THD *thd, Item_func *item) item. RETURN VALUES - 0 ok - 1 Got error. Stored with my_error(). + FALSE ok + TRUE Got error. Stored with my_error(). */ bool @@ -216,7 +216,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) const_item_cache=1; if (check_stack_overrun(thd, buff)) - return 1; // Fatal error if flag is set! + return TRUE; // Fatal error if flag is set! if (arg_count) { // Print purify happy for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) @@ -228,7 +228,7 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) */ if ((!(*arg)->fixed && (*arg)->fix_fields(thd, tables, arg)) || (*arg)->check_cols(allowed_arg_cols)) - return 1; /* purecov: inspected */ + return TRUE; /* purecov: inspected */ item= *arg; if (item->maybe_null) maybe_null=1; @@ -240,10 +240,10 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } } fix_length_and_dec(); - if (thd->net.last_errno) // An error inside fix_length_and_dec occured - return 1; + if (thd->net.report_error) // An error inside fix_length_and_dec occured + return TRUE; fixed= 1; - return 0; + return FALSE; } bool Item_func::walk (Item_processor processor, byte *argument) @@ -1568,7 +1568,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, DBUG_ENTER("Item_udf_func::fix_fields"); if (check_stack_overrun(thd, buff)) - DBUG_RETURN(1); // Fatal error flag is set! + DBUG_RETURN(TRUE); // Fatal error flag is set! udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1); @@ -1576,7 +1576,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, { my_printf_error(ER_CANT_FIND_UDF,ER(ER_CANT_FIND_UDF),MYF(0),u_d->name.str, errno); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } u_d=tmp_udf; args=arguments; @@ -1593,7 +1593,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, { free_udf(u_d); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } uint i; Item **arg,**arg_end; @@ -1606,7 +1606,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, // we can't assign 'item' before, because fix_fields() can change arg Item *item= *arg; if (item->check_cols(1)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); /* TODO: We should think about this. It is not always right way just to set an UDF result to return my_charset_bin @@ -1639,7 +1639,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, sizeof(long)))) { free_udf(u_d); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } func->fix_length_and_dec(); @@ -1698,7 +1698,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), u_d->name.str, thd->net.last_error); free_udf(u_d); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } func->max_length=min(initid.max_length,MAX_BLOB_WIDTH); func->maybe_null=initid.maybe_null; @@ -1710,9 +1710,9 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, { my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), u_d->name.str, ER(ER_UNKNOWN_ERROR)); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -2322,7 +2322,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */ if (Item_func::fix_fields(thd, tables, ref) || !(entry= get_variable(&thd->user_vars, name, 1))) - return 1; + return TRUE; /* Remember the last query which updated it, this way a query can later know if this variable is a constant item in the query (it is if update_query_id @@ -2331,7 +2331,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, entry->update_query_id= thd->query_id; entry->collation.set(args[0]->collation); cached_result_type= args[0]->result_type(); - return 0; + return FALSE; } @@ -2490,7 +2490,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, will be catched by thd->net.report_error check in sql_set_variables(). RETURN - 0 - OK. + FALSE OK. */ bool @@ -2520,7 +2520,7 @@ Item_func_set_user_var::check() DBUG_ASSERT(0); break; } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -2968,7 +2968,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) !args[0]->const_during_execution()) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST"); - return 1; + return TRUE; } const_item_cache=0; @@ -2991,7 +2991,7 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) if (key == NO_SUCH_KEY && !(flags & FT_BOOL)) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); - return 1; + return TRUE; } table=((Item_field *)item)->field->table; table->fulltext_searched=1; @@ -3202,7 +3202,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, { if (!var->is_struct()) { - net_printf(thd, ER_VARIABLE_IS_NOT_STRUCT, base_name->str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str); return 0; } } diff --git a/sql/item_row.cc b/sql/item_row.cc index f6623e80734..0cfe8287dcb 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -62,7 +62,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) { if ((*arg)->fix_fields(thd, tabl, arg)) - return 1; + return TRUE; // we can't assign 'item' before, because fix_fields() can change arg Item *item= *arg; used_tables_cache |= item->used_tables(); @@ -81,7 +81,7 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) with_sum_func= with_sum_func || item->with_sum_func; } fixed= 1; - return 0; + return FALSE; } void Item_row::split_sum_func(Item **ref_pointer_array, List &fields) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 25bb2701101..8fe6e5c81dd 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -66,7 +66,7 @@ void Item_subselect::init(st_select_lex *select_lex, parsing_place= unit->item->parsing_place; unit->item->engine= 0; unit->item= this; - engine->change_item(this, result); + engine->change_result(this, result); } else { @@ -133,13 +133,13 @@ Item_subselect::select_transformer(JOIN *join) bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) { char const *save_where= thd_param->where; - int res; + bool res; DBUG_ASSERT(fixed == 0); engine->set_thd((thd= thd_param)); if (check_stack_overrun(thd, (gptr)&res)) - return 1; + return TRUE; res= engine->prepare(); @@ -168,7 +168,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) if (substype() == SINGLEROW_SUBS && (*ref)->with_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0)); - return 1; + return TRUE; } return ret; } @@ -176,7 +176,7 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) if (engine->cols() > max_columns) { my_error(ER_OPERAND_COLUMNS, MYF(0), 1); - return 1; + return TRUE; } fix_length_and_dec(); } @@ -1493,12 +1493,12 @@ void subselect_indexsubquery_engine::print(String *str) res new select_result object RETURN - 0 OK - -1 error + FALSE OK + TRUE error */ -int subselect_single_select_engine::change_item(Item_subselect *si, - select_subselect *res) +bool subselect_single_select_engine::change_result(Item_subselect *si, + select_subselect *res) { item= si; result= res; @@ -1515,12 +1515,12 @@ int subselect_single_select_engine::change_item(Item_subselect *si, res new select_result object RETURN - 0 OK - -1 error + FALSE OK + TRUE error */ -int subselect_union_engine::change_item(Item_subselect *si, - select_subselect *res) +bool subselect_union_engine::change_result(Item_subselect *si, + select_subselect *res) { item= si; int rc= unit->change_result(res, result); @@ -1538,12 +1538,13 @@ int subselect_union_engine::change_item(Item_subselect *si, res new select_result object RETURN - -1 error + FALSE OK + TRUE error */ -int subselect_uniquesubquery_engine::change_item(Item_subselect *si, - select_subselect *res) +bool subselect_uniquesubquery_engine::change_result(Item_subselect *si, + select_subselect *res) { DBUG_ASSERT(0); - return -1; + return TRUE; } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 4a325c4b224..e45cd6911e9 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -290,7 +290,7 @@ public: virtual table_map upper_select_const_tables()= 0; static table_map calc_const_tables(TABLE_LIST *); virtual void print(String *str)= 0; - virtual int change_item(Item_subselect *si, select_subselect *result)= 0; + virtual bool change_result(Item_subselect *si, select_subselect *result)= 0; }; @@ -314,7 +314,7 @@ public: void exclude(); table_map upper_select_const_tables(); void print (String *str); - int change_item(Item_subselect *si, select_subselect *result); + bool change_result(Item_subselect *si, select_subselect *result); }; @@ -334,7 +334,7 @@ public: void exclude(); table_map upper_select_const_tables(); void print (String *str); - int change_item(Item_subselect *si, select_subselect *result); + bool change_result(Item_subselect *si, select_subselect *result); }; @@ -363,7 +363,7 @@ public: void exclude(); table_map upper_select_const_tables() { return 0; } void print (String *str); - int change_item(Item_subselect *si, select_subselect *result); + bool change_result(Item_subselect *si, select_subselect *result); }; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index d400c198828..bf3601931ca 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -215,12 +215,12 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) DBUG_ASSERT(fixed == 0); if (save_args_for_prepared_statement(thd)) - return 1; + return TRUE; if (!thd->allow_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); - return 1; + return TRUE; } thd->allow_sum_func=0; // No included group funcs decimals=0; @@ -228,7 +228,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) for (uint i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) - return 1; + return TRUE; if (decimals < args[i]->decimals) decimals=args[i]->decimals; maybe_null |= args[i]->maybe_null; @@ -239,7 +239,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) fix_length_and_dec(); thd->allow_sum_func=1; // Allow group functions fixed= 1; - return 0; + return FALSE; } @@ -249,13 +249,13 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) DBUG_ASSERT(fixed == 0); if (save_args_for_prepared_statement(thd)) - return 1; + return TRUE; Item *item= args[0]; if (!thd->allow_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); - return 1; + return TRUE; } thd->allow_sum_func=0; // No included group funcs @@ -263,7 +263,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!item->fixed && item->fix_fields(thd, tables, args) || (item= args[0])->check_cols(1)) - return 1; + return TRUE; hybrid_type= item->result_type(); if (hybrid_type == INT_RESULT) @@ -294,7 +294,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) else hybrid_field_type= Item::field_type(); fixed= 1; - return 0; + return FALSE; } @@ -2060,12 +2060,12 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) DBUG_ASSERT(fixed == 0); if (save_args_for_prepared_statement(thd)) - return 1; + return TRUE; if (!thd->allow_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); - return 1; + return TRUE; } thd->allow_sum_func= 0; @@ -2079,7 +2079,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) for (i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) - return 1; + return TRUE; if (i < arg_count_field) maybe_null|= args[i]->maybe_null; } @@ -2089,10 +2089,10 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) max_length= group_concat_max_len; thd->allow_sum_func= 1; if (!(tmp_table_param= new TMP_TABLE_PARAM)) - return 1; + return TRUE; tables_list= tables; fixed= 1; - return 0; + return FALSE; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 988529c845c..76aa06bf7cc 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1671,7 +1671,7 @@ Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **re { String str; if (Item_date_func::fix_fields(thd_arg, tables_arg, ref)) - return 1; + return TRUE; tz_tables= thd_arg->lex->time_zone_tables_used; @@ -1681,7 +1681,7 @@ Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **re if (args[2]->const_item()) to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); - return 0; + return FALSE; } diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 5582537bdbb..c69bd02ae5b 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -50,7 +50,7 @@ public: { DBUG_ASSERT(fixed == 0); fixed= 1; - return 0; + return FALSE; } Item *copy_or_same(THD* thd) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b4fba907fbf..99fc54fd73b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -418,17 +418,17 @@ bool check_one_table_access(THD *thd, ulong privilege, bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list); -int multi_update_precheck(THD *thd, TABLE_LIST *tables); -int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); -int mysql_multi_update_prepare(THD *thd); -int mysql_multi_delete_prepare(THD *thd); -int mysql_insert_select_prepare(THD *thd); -int insert_select_precheck(THD *thd, TABLE_LIST *tables); -int update_precheck(THD *thd, TABLE_LIST *tables); -int delete_precheck(THD *thd, TABLE_LIST *tables); -int insert_precheck(THD *thd, TABLE_LIST *tables, bool update); -int create_table_precheck(THD *thd, TABLE_LIST *tables, - TABLE_LIST *create_table); +bool multi_update_precheck(THD *thd, TABLE_LIST *tables); +bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count); +bool mysql_multi_update_prepare(THD *thd); +bool mysql_multi_delete_prepare(THD *thd); +bool mysql_insert_select_prepare(THD *thd); +bool insert_select_precheck(THD *thd, TABLE_LIST *tables); +bool update_precheck(THD *thd, TABLE_LIST *tables); +bool delete_precheck(THD *thd, TABLE_LIST *tables); +bool insert_precheck(THD *thd, TABLE_LIST *tables, bool update); +bool create_table_precheck(THD *thd, TABLE_LIST *tables, + TABLE_LIST *create_table); Item *negate_expression(THD *thd, Item *expr); #include "sql_class.h" #include "opt_range.h" @@ -475,12 +475,12 @@ struct Query_cache_query_flags #define prepare_execute(A) ((A)->command == COM_EXECUTE) -int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); -int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); -int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); +bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); +bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); +bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent); void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags); -int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, - my_bool drop_temporary); +bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, + my_bool drop_temporary); int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool drop_view, bool log_query); int mysql_rm_table_part2_with_lock(THD *thd, TABLE_LIST *tables, @@ -507,7 +507,7 @@ extern "C" pthread_handler_decl(handle_one_connection,arg); extern "C" pthread_handler_decl(handle_bootstrap,arg); void end_thread(THD *thd,bool put_in_cache); void flush_thread_cache(); -int mysql_execute_command(THD *thd); +bool mysql_execute_command(THD *thd); bool do_command(THD *thd); bool dispatch_command(enum enum_server_command command, THD *thd, char* packet, uint packet_length); @@ -526,22 +526,22 @@ bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables, bool no_errors); bool check_global_access(THD *thd, ulong want_access); -int mysql_backup_table(THD* thd, TABLE_LIST* table_list); -int mysql_restore_table(THD* thd, TABLE_LIST* table_list); - -int mysql_checksum_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_check_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_repair_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_analyze_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, - HA_CHECK_OPT* check_opt); -int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list, - LEX_STRING *key_cache_name); -int mysql_preload_keys(THD* thd, TABLE_LIST* table_list); +bool mysql_backup_table(THD* thd, TABLE_LIST* table_list); +bool mysql_restore_table(THD* thd, TABLE_LIST* table_list); + +bool mysql_checksum_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_check_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_repair_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_analyze_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_optimize_table(THD* thd, TABLE_LIST* table_list, + HA_CHECK_OPT* check_opt); +bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list, + LEX_STRING *key_cache_name); +bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list); int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache, KEY_CACHE *dst_cache); @@ -554,20 +554,20 @@ int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, List &fields, List &all_fields, ORDER *order, bool *hidden_group_fields); -int handle_select(THD *thd, LEX *lex, select_result *result); -int mysql_select(THD *thd, Item ***rref_pointer_array, - TABLE_LIST *tables, uint wild_num, List &list, - COND *conds, uint og_num, ORDER *order, ORDER *group, - Item *having, ORDER *proc_param, ulong select_type, - select_result *result, SELECT_LEX_UNIT *unit, - SELECT_LEX *select_lex); +bool handle_select(THD *thd, LEX *lex, select_result *result); +bool mysql_select(THD *thd, Item ***rref_pointer_array, + TABLE_LIST *tables, uint wild_num, List &list, + COND *conds, uint og_num, ORDER *order, ORDER *group, + Item *having, ORDER *proc_param, ulong select_type, + select_result *result, SELECT_LEX_UNIT *unit, + SELECT_LEX *select_lex); void free_underlaid_joins(THD *thd, SELECT_LEX *select); -int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, - select_result *result); +bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, + select_result *result); int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, select_result *result); -int mysql_union(THD *thd, LEX *lex, select_result *result, - SELECT_LEX_UNIT *unit); +bool mysql_union(THD *thd, LEX *lex, select_result *result, + SELECT_LEX_UNIT *unit); int mysql_handle_derived(LEX *lex); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, Item ***copy_func, Field **from_field, @@ -577,61 +577,61 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, List &keys, uint &db_options, handler *file, KEY *&key_info_buffer, uint &key_count, int select_field_count); -int mysql_create_table(THD *thd,const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List &fields, List &keys, - bool tmp_table, uint select_field_count); +bool mysql_create_table(THD *thd,const char *db, const char *table_name, + HA_CREATE_INFO *create_info, + List &fields, List &keys, + bool tmp_table, uint select_field_count); TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE_LIST *create_table, List *extra_fields, List *keys, List *items, - MYSQL_LOCK **lock); -int mysql_alter_table(THD *thd, char *new_db, char *new_name, - HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - List &fields, - List &keys, - uint order_num, ORDER *order, - enum enum_duplicates handle_duplicates, - ALTER_INFO *alter_info, bool do_send_ok=1); -int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); -int mysql_create_like_table(THD *thd, TABLE_LIST *table, - HA_CREATE_INFO *create_info, - Table_ident *src_table); + MYSQL_LOCK **lock); +bool mysql_alter_table(THD *thd, char *new_db, char *new_name, + HA_CREATE_INFO *create_info, + TABLE_LIST *table_list, + List &fields, + List &keys, + uint order_num, ORDER *order, + enum enum_duplicates handle_duplicates, + ALTER_INFO *alter_info, bool do_send_ok=1); +bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool do_send_ok); +bool mysql_create_like_table(THD *thd, TABLE_LIST *table, + HA_CREATE_INFO *create_info, + Table_ident *src_table); bool mysql_rename_table(enum db_type base, const char *old_db, const char * old_name, const char *new_db, const char * new_name); -int mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys); -int mysql_drop_index(THD *thd, TABLE_LIST *table_list, - ALTER_INFO *alter_info); +bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys); +bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, + ALTER_INFO *alter_info); int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, Item **conds, uint order_num, ORDER *order); -int mysql_update(THD *thd,TABLE_LIST *tables,List &fields, - List &values,COND *conds, - uint order_num, ORDER *order, ha_rows limit, - enum enum_duplicates handle_duplicates); -int mysql_multi_update(THD *thd, TABLE_LIST *table_list, - List *fields, List *values, - COND *conds, ulong options, - enum enum_duplicates handle_duplicates, - SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); -int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, - List &fields, List_item *values, - List &update_fields, - List &update_values, enum_duplicates duplic); -int mysql_insert(THD *thd,TABLE_LIST *table,List &fields, - List &values, List &update_fields, - List &update_values, enum_duplicates flag); +bool mysql_update(THD *thd,TABLE_LIST *tables,List &fields, + List &values,COND *conds, + uint order_num, ORDER *order, ha_rows limit, + enum enum_duplicates handle_duplicates); +bool mysql_multi_update(THD *thd, TABLE_LIST *table_list, + List *fields, List *values, + COND *conds, ulong options, + enum enum_duplicates handle_duplicates, + SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); +bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, + List &fields, List_item *values, + List &update_fields, + List &update_values, enum_duplicates duplic); +bool mysql_insert(THD *thd,TABLE_LIST *table,List &fields, + List &values, List &update_fields, + List &update_values, enum_duplicates flag); int check_that_all_fields_are_given_values(THD *thd, TABLE *entry); -int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); -int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, - ha_rows rows, ulong options); -int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); -int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create); +bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); +bool mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, SQL_LIST *order, + ha_rows rows, ulong options); +bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); +bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update); TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem, bool *refresh); @@ -683,45 +683,45 @@ void free_des_key_file(); #endif /* HAVE_OPENSSL */ /* sql_do.cc */ -int mysql_do(THD *thd, List &values); +bool mysql_do(THD *thd, List &values); /* sql_show.cc */ -int mysqld_show_dbs(THD *thd,const char *wild); -int mysqld_show_open_tables(THD *thd,const char *wild); -int mysqld_show_tables(THD *thd, const char *db, const char *wild, - bool verbose); -int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild); -int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild, - bool verbose); -int mysqld_show_keys(THD *thd, TABLE_LIST *table); -int mysqld_show_logs(THD *thd); +bool mysqld_show_dbs(THD *thd,const char *wild); +bool mysqld_show_open_tables(THD *thd,const char *wild); +bool mysqld_show_tables(THD *thd, const char *db, const char *wild, + bool verbose); +bool mysqld_extend_show_tables(THD *thd,const char *db,const char *wild); +bool mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild, + bool verbose); +bool mysqld_show_keys(THD *thd, TABLE_LIST *table); +bool mysqld_show_logs(THD *thd); void append_identifier(THD *thd, String *packet, const char *name, uint length); void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild); int mysqld_dump_create_info(THD *thd, TABLE *table, int fd = -1); -int mysqld_show_create(THD *thd, TABLE_LIST *table_list); -int mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create); +bool mysqld_show_create(THD *thd, TABLE_LIST *table_list); +bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create); void mysqld_list_processes(THD *thd,const char *user,bool verbose); int mysqld_show_status(THD *thd); int mysqld_show_variables(THD *thd,const char *wild); -int mysqld_show(THD *thd, const char *wild, show_var_st *variables, +bool mysqld_show(THD *thd, const char *wild, show_var_st *variables, enum enum_var_type value_type, pthread_mutex_t *mutex, struct system_status_var *status_var); int mysql_find_files(THD *thd,List *files, const char *db, const char *path, const char *wild, bool dir); -int mysqld_show_charsets(THD *thd,const char *wild); -int mysqld_show_collations(THD *thd,const char *wild); -int mysqld_show_storage_engines(THD *thd); -int mysqld_show_privileges(THD *thd); -int mysqld_show_column_types(THD *thd); -int mysqld_help (THD *thd, const char *text); +bool mysqld_show_charsets(THD *thd,const char *wild); +bool mysqld_show_collations(THD *thd,const char *wild); +bool mysqld_show_storage_engines(THD *thd); +bool mysqld_show_privileges(THD *thd); +bool mysqld_show_column_types(THD *thd); +bool mysqld_help (THD *thd, const char *text); void calc_sum_of_all_status(STATUS_VAR *to); /* sql_prepare.cc */ -int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, - LEX_STRING *name=NULL); +bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, + LEX_STRING *name=NULL); void mysql_stmt_execute(THD *thd, char *packet, uint packet_length); void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name); void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length); @@ -736,15 +736,15 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, uint void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, uint code, const char *format, ...); void mysql_reset_errors(THD *thd); -my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show); +bool mysqld_show_warnings(THD *thd, ulong levels_to_show); /* sql_handler.cc */ -int mysql_ha_open(THD *thd, TABLE_LIST *tables); -int mysql_ha_close(THD *thd, TABLE_LIST *tables, - bool dont_send_ok=0, bool dont_lock=0, bool no_alias=0); +bool mysql_ha_open(THD *thd, TABLE_LIST *tables); +bool mysql_ha_close(THD *thd, TABLE_LIST *tables, + bool dont_send_ok=0, bool dont_lock=0, bool no_alias=0); int mysql_ha_close_list(THD *thd, TABLE_LIST *tables, bool flushed=0); -int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, - List *,enum ha_rkey_function,Item *,ha_rows,ha_rows); +bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, + List *,enum ha_rkey_function,Item *,ha_rows,ha_rows); /* sql_base.cc */ void set_item_name(Item *item,char *pos,uint length); @@ -778,16 +778,16 @@ bool insert_fields(THD *thd,TABLE_LIST *tables, bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds); int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, List *sum_func_list, uint wild_num); -int setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables, - List &item, bool set_query_id, - List *sum_func_list, bool allow_sum_func); +bool setup_fields(THD *thd, Item** ref_pointer_array, TABLE_LIST *tables, + List &item, bool set_query_id, + List *sum_func_list, bool allow_sum_func); int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); int setup_ftfuncs(SELECT_LEX* select); int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); void wait_for_refresh(THD *thd); int open_tables(THD *thd, TABLE_LIST *tables, uint *counter); int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables); -int open_and_lock_tables(THD *thd,TABLE_LIST *tables); +bool open_and_lock_tables(THD *thd,TABLE_LIST *tables); int lock_tables(THD *thd, TABLE_LIST *tables, uint counter); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list); @@ -837,9 +837,9 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table, bool eval_const_cond(COND *cond); /* sql_load.cc */ -int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list, - List &fields, enum enum_duplicates handle_duplicates, - bool local_file,thr_lock_type lock_type); +bool mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list, + List &fields, enum enum_duplicates handle_duplicates, + bool local_file,thr_lock_type lock_type); int write_record(THD *thd, TABLE *table, COPY_INFO *info); /* sql_manager.cc */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index db81b14c9c9..c408478cb15 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1145,7 +1145,7 @@ static void server_init(void) WSADATA WsaData; if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData)) { - my_message(0,"WSAStartup Failed\n",MYF(0)); + my_error(ER_WSAS_FAILED, MYF(0)); unireg_abort(1); } } @@ -1298,8 +1298,9 @@ void yyerror(const char *s) /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) s=ER(ER_SYNTAX_ERROR); - net_printf(thd,ER_PARSE_ERROR, s, yytext ? (char*) yytext : "", - thd->lex->yylineno); + my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), s, + (yytext ? (char*) yytext : ""), + thd->lex->yylineno); } @@ -2091,6 +2092,11 @@ extern "C" int my_message_sql(uint error, const char *str, THD *thd; DBUG_ENTER("my_message_sql"); DBUG_PRINT("error", ("error: %u message: '%s'", error, str)); + /* + Put here following assertion when situation with EE_* error codes + will be fixed + DBUG_ASSERT(error != 0); + */ if ((thd= current_thd)) { if (thd->spcont && @@ -2098,6 +2104,9 @@ extern "C" int my_message_sql(uint error, const char *str, { DBUG_RETURN(0); } + + thd->query_error= 1; // needed to catch query errors during replication + /* thd->lex->current_select == 0 if lex structure is not inited (not query command (COM_QUERY)) @@ -2112,6 +2121,9 @@ extern "C" int my_message_sql(uint error, const char *str, { NET *net= &thd->net; net->report_error= 1; +#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ + query_cache_abort(net); +#endif if (!net->last_error[0]) // Return only first message { strmake(net->last_error, str, sizeof(net->last_error)-1); @@ -3381,7 +3393,7 @@ static void create_new_thread(THD *thd) ("Can't create thread to handle request (error %d)", error)); thread_count--; - thd->killed= THD::KILL_CONNECTION; // Safety + thd->killed= THD::KILL_CONNECTION; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); statistic_increment(aborted_connects,&LOCK_status); net_printf(thd,ER_CANT_CREATE_THREAD,error); diff --git a/sql/protocol.cc b/sql/protocol.cc index 187989158df..c92d25f3f4d 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -70,9 +70,6 @@ void send_error(THD *thd, uint sql_errno, const char *err) { DBUG_VOID_RETURN; } -#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/ - query_cache_abort(net); -#endif thd->query_error= 1; // needed to catch query errors during replication if (!err) { @@ -614,7 +611,7 @@ bool Protocol::send_fields(List *list, int flags) DBUG_RETURN(prepare_for_send(list)); err: - send_error(thd,ER_OUT_OF_RESOURCES); /* purecov: inspected */ + my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } diff --git a/sql/protocol_cursor.cc b/sql/protocol_cursor.cc index 8904aba7b88..0954bb5466f 100644 --- a/sql/protocol_cursor.cc +++ b/sql/protocol_cursor.cc @@ -85,7 +85,7 @@ bool Protocol_cursor::send_fields(List *list, int flags) DBUG_RETURN(FALSE); err: - send_error(thd, ER_OUT_OF_RESOURCES); /* purecov: inspected */ + my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */ DBUG_RETURN(TRUE); /* purecov: inspected */ } diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 10ff5fa3596..6ba1ce6267f 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -196,7 +196,6 @@ err: my_message(ER_UNKNOWN_ERROR, "Wrong parameters to function register_slave", MYF(0)); err2: - send_error(thd); return 1; } @@ -440,7 +439,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, This function is broken now. See comment for translate_master(). */ -int show_new_master(THD* thd) +bool show_new_master(THD* thd) { Protocol *protocol= thd->protocol; DBUG_ENTER("show_new_master"); @@ -454,7 +453,7 @@ int show_new_master(THD* thd) if (errmsg[0]) my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), "SHOW NEW MASTER", errmsg); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } else { @@ -463,14 +462,14 @@ int show_new_master(THD* thd) MYSQL_TYPE_LONGLONG)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); protocol->store(lex_mi->log_file_name, &my_charset_bin); protocol->store((ulonglong) lex_mi->pos); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } } @@ -633,7 +632,7 @@ err: } -int show_slave_hosts(THD* thd) +bool show_slave_hosts(THD* thd) { List field_list; Protocol *protocol= thd->protocol; @@ -655,7 +654,7 @@ int show_slave_hosts(THD* thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); pthread_mutex_lock(&LOCK_slave_list); @@ -676,12 +675,12 @@ int show_slave_hosts(THD* thd) if (protocol->write()) { pthread_mutex_unlock(&LOCK_slave_list); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } pthread_mutex_unlock(&LOCK_slave_list); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -762,7 +761,7 @@ static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db, - No active transaction (flush_relay_log_info would not work in this case) */ -int load_master_data(THD* thd) +bool load_master_data(THD* thd) { MYSQL mysql; MYSQL_RES* master_status_res = 0; @@ -784,16 +783,15 @@ int load_master_data(THD* thd) (error=terminate_slave_threads(active_mi,restart_thread_mask, 1 /*skip lock*/))) { - send_error(thd,error); + my_error(error, MYF(0)); unlock_slave_threads(active_mi); pthread_mutex_unlock(&LOCK_active_mi); - return 1; + return TRUE; } if (connect_to_master(thd, &mysql, active_mi)) { - net_printf(thd, error= ER_CONNECT_TO_MASTER, - mysql_error(&mysql)); + my_error(error= ER_CONNECT_TO_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -805,8 +803,7 @@ int load_master_data(THD* thd) if (mysql_real_query(&mysql, "SHOW DATABASES", 14) || !(db_res = mysql_store_result(&mysql))) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -819,7 +816,7 @@ int load_master_data(THD* thd) if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*)))) { - net_printf(thd, error = ER_OUTOFMEMORY); + my_error(error = ER_OUTOFMEMORY, MYF(0)); goto err; } @@ -833,8 +830,7 @@ int load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW MASTER STATUS",18) || !(master_status_res = mysql_store_result(&mysql))) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -879,7 +875,6 @@ int load_master_data(THD* thd) if (mysql_create_db(thd, db, &create_info, 1)) { - send_error(thd, 0, 0); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; } @@ -888,8 +883,7 @@ int load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW TABLES", 11) || !(*cur_table_res = mysql_store_result(&mysql))) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; } @@ -927,7 +921,7 @@ int load_master_data(THD* thd) if (init_master_info(active_mi, master_info_file, relay_log_info_file, 0)) - send_error(thd, ER_MASTER_INFO); + my_error(ER_MASTER_INFO, MYF(0)); strmake(active_mi->master_log_name, row[0], sizeof(active_mi->master_log_name)); active_mi->master_log_pos= my_strtoll10(row[1], (char**) 0, &error); @@ -946,8 +940,7 @@ int load_master_data(THD* thd) if (mysql_real_query(&mysql, "UNLOCK TABLES", 13)) { - net_printf(thd, error = ER_QUERY_ON_MASTER, - mysql_error(&mysql)); + my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } } @@ -956,10 +949,10 @@ int load_master_data(THD* thd) 0 /* not only reset, but also reinit */, &errmsg)) { - send_error(thd, 0, "Failed purging old relay logs"); + my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); unlock_slave_threads(active_mi); pthread_mutex_unlock(&LOCK_active_mi); - return 1; + return TRUE; } pthread_mutex_lock(&active_mi->rli.data_lock); active_mi->rli.group_master_log_pos = active_mi->master_log_pos; diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h index a9c504330ab..1ced69fdc3c 100644 --- a/sql/repl_failsafe.h +++ b/sql/repl_failsafe.h @@ -24,11 +24,11 @@ int update_slave_list(MYSQL* mysql, MASTER_INFO* mi); extern HASH slave_list; -int load_master_data(THD* thd); +bool load_master_data(THD* thd); int connect_to_master(THD *thd, MYSQL* mysql, MASTER_INFO* mi); -int show_new_master(THD* thd); -int show_slave_hosts(THD* thd); +bool show_new_master(THD* thd); +bool show_slave_hosts(THD* thd); int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg); void init_slave_list(); void end_slave_list(); diff --git a/sql/set_var.cc b/sql/set_var.cc index 33c6a380223..e08a65c793a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1520,8 +1520,8 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) { if (var_type != OPT_DEFAULT) { - net_printf(thd, ER_INCORRECT_GLOBAL_LOCAL_VAR, - name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); + my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), + name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); return 0; } /* As there was no local variable, return the global value */ @@ -1564,7 +1564,7 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) return tmp; } default: - net_printf(thd, ER_VAR_CANT_BE_READ, name); + my_error(ER_VAR_CANT_BE_READ, MYF(0), name); } return 0; } @@ -1950,8 +1950,8 @@ bool sys_var_character_set_server::check(THD *thd, set_var *var) (mysql_bin_log.is_open() || active_mi->slave_running || active_mi->rli.slave_running)) { - my_printf_error(0, "Binary logging and replication forbid changing \ -the global server character set or collation", MYF(0)); + my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0), + "character set, collation"); return 1; } return sys_var_character_set::check(thd,var); @@ -2057,8 +2057,8 @@ bool sys_var_collation_server::check(THD *thd, set_var *var) (mysql_bin_log.is_open() || active_mi->slave_running || active_mi->rli.slave_running)) { - my_printf_error(0, "Binary logging and replication forbid changing \ -the global server character set or collation", MYF(0)); + my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0), + "character set, collation"); return 1; } return sys_var_collation::check(thd,var); @@ -2407,8 +2407,7 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) (mysql_bin_log.is_open() || active_mi->slave_running || active_mi->rli.slave_running)) { - my_printf_error(0, "Binary logging and replication forbid changing " - "of the global server time zone", MYF(0)); + my_error(ER_LOGING_PROHIBIT_CHANGING_OF, MYF(0), "time zone"); return 1; } #endif @@ -2686,9 +2685,6 @@ void set_var_free() length Length of variable. zero means that we should use strlen() on the variable - NOTE - We have to use net_printf() as this is called during the parsing stage - RETURN VALUES pointer pointer to variable definitions 0 Unknown variable (error message is given) @@ -2701,7 +2697,7 @@ sys_var *find_sys_var(const char *str, uint length) length ? length : strlen(str)); if (!var) - net_printf(current_thd, ER_UNKNOWN_SYSTEM_VARIABLE, (char*) str); + my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str); return var; } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 301ac6133ca..3f5814df575 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -398,3 +398,22 @@ character-set=latin2 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 128859a5505..fa5d8f8a8c7 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -389,3 +389,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 3ad8d91bba7..7dbd32c9db4 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -398,3 +398,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 1878d6e2da2..8fe08ddc7a7 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -386,3 +386,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index af14aeac85c..b52aa6154ec 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -391,3 +391,22 @@ character-set=latin7 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index b731f398a2f..43a77fdec42 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -386,3 +386,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index ff797119971..1b3a916c777 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -399,3 +399,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index f5db8296d14..baf88d7fead 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -386,3 +386,22 @@ character-set=greek "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 0b410dc1ac7..2c1efa97e30 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -391,3 +391,22 @@ character-set=latin2 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 0c0ccdc0a74..5859e5380ef 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -386,3 +386,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index bd9dd98d525..c58acde49cd 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -390,3 +390,22 @@ character-set=ujis "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 9ab305bc2d8..74e42b09fc7 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -386,3 +386,22 @@ character-set=euckr "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index c8166a777bf..1bce2767784 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -388,3 +388,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 07f7381091d..c09aa257ead 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -388,3 +388,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 43cf08666ac..96985de759d 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -391,3 +391,22 @@ character-set=latin2 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 827c49d3f1f..c9dac302f5e 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -388,3 +388,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index a3c16ea5023..25c06397d7c 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -391,3 +391,22 @@ character-set=latin2 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index c5988fca6d5..71b21268dba 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -391,3 +391,22 @@ character-set=koi8r "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION ÄÌÑ ÎÅÏÂÎÏ×ÌÑÅÍÏÇÏ VIEW '%-.64s.%-.64s'" "ÐÒÏ×ÅÒËÁ CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÐÒÏ×ÁÌÉÌÁÓØ" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 5a08ae4ba54..4228f3a3a4e 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -379,3 +379,22 @@ character-set=cp1250 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index a6bab89d689..9b9508eeca9 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -394,3 +394,22 @@ character-set=latin2 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 11bc53cde16..5af6d647fd3 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -390,3 +390,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 6d9a6b98204..85866007367 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -386,3 +386,22 @@ character-set=latin1 "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION on non-updatable view '%-.64s.%-.64s'" "CHECK OPTION failed '%-.64s.%-.64s'" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 03f3172c2fb..4bb3a6a1aab 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -392,3 +392,22 @@ character-set=koi8u "Illegal %s '%-.64s' value found during parsing", "CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÝÏ ÎÅ ÍÏÖÅ ÂÕÔÉ ÏÎÏ×ÌÅÎÎÉÍ" "ÐÅÒÅצÒËÁ CHECK OPTION ÄÌÑ VIEW '%-.64s.%-.64s' ÎÅ ÐÒÏÊÛÌÁ" +"Failed purging old relay logs: %s" +"Password hash should be a %d-digit hexadecimal number" +"Target log not found in binlog index" +"I/O error reading log index file" +"Server configuration does not permit binlog purge" +"Failed on fseek()" +"Fatal error during log purge" +"A purgeable log is in use, will not purge" +"Unknown error during log purge" +"Failed initializing relay log position: %s" +"You are not using binary logging" +"The '%-.64s' syntax is reserved for purposes internal to the MySQL server" +"WSAStartup Failed" +"Can't handle procedures with differents groups yet" +"Select must have a group with this procedure" +"Can't use ORDER clause with this procedure" +"Binary logging and replication forbid changing the global server %s" +"Can't map file: %-.64s, errno: %d" +"Wrong magic in %-.64s" diff --git a/sql/slave.cc b/sql/slave.cc index 2c6fb06b7cb..2ed554e65c8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1489,7 +1489,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, packet_len= my_net_read(net); // read create table statement if (packet_len == packet_error) { - send_error(thd, ER_MASTER_NET_READ); + my_error(ER_MASTER_NET_READ, MYF(0)); DBUG_RETURN(1); } if (net->read_pos[0] == 255) // error from master @@ -1498,7 +1498,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, err_msg= (char*) net->read_pos + ((mysql->server_capabilities & CLIENT_PROTOCOL_41) ? 3+SQLSTATE_LENGTH+1 : 3); - net_printf(thd, ER_MASTER, err_msg); + my_error(ER_MASTER, MYF(0), err_msg); DBUG_RETURN(1); } thd->command = COM_TABLE_DUMP; @@ -1507,7 +1507,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, if (!(query = thd->strmake((char*) net->read_pos, packet_len))) { sql_print_error("create_table_from_dump: out of memory"); - net_printf(thd, ER_GET_ERRNO, "Out of memory"); + my_error(ER_GET_ERRNO, MYF(0), "Out of memory"); DBUG_RETURN(1); } thd->query= query; @@ -1521,7 +1521,6 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, /* Drop the table if 'overwrite' is true */ if (overwrite && mysql_rm_table(thd,&tables,1,0)) /* drop if exists */ { - send_error(thd); sql_print_error("create_table_from_dump: failed to drop the table"); goto err; } @@ -1544,7 +1543,6 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, tables.lock_type = TL_WRITE; if (!open_ltable(thd, &tables, TL_WRITE)) { - send_error(thd,0,0); // Send error from open_ltable sql_print_error("create_table_from_dump: could not open created table"); goto err; } @@ -1554,7 +1552,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, /* Copy the data file */ if (file->net_read_dump(net)) { - net_printf(thd, ER_MASTER_NET_READ); + my_error(ER_MASTER_NET_READ, MYF(0)); sql_print_error("create_table_from_dump: failed in\ handler::net_read_dump()"); goto err; @@ -1574,7 +1572,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, error=file->repair(thd,&check_opt) != 0; thd->net.vio = save_vio; if (error) - net_printf(thd, ER_INDEX_REBUILD,tables.table->real_name); + my_error(ER_INDEX_REBUILD, MYF(0), tables.table->real_name); err: close_thread_tables(thd); @@ -1597,12 +1595,11 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, { if (!(mysql = mysql_init(NULL))) { - send_error(thd); // EOM DBUG_RETURN(1); } if (connect_to_master(thd, mysql, mi)) { - net_printf(thd, ER_CONNECT_TO_MASTER, mysql_error(mysql)); + my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql)); mysql_close(mysql); DBUG_RETURN(1); } @@ -1626,7 +1623,7 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, if (!called_connected) mysql_close(mysql); if (errmsg && thd->vio_ok()) - send_error(thd, error, errmsg); + my_message(error, errmsg, MYF(0)); DBUG_RETURN(test(error)); // Return 1 on error } @@ -2263,7 +2260,7 @@ void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a) } } -int show_master_info(THD* thd, MASTER_INFO* mi) +bool show_master_info(THD* thd, MASTER_INFO* mi) { // TODO: fix this for multi-master List field_list; @@ -2327,7 +2324,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (mi->host[0]) { @@ -2426,10 +2423,10 @@ int show_master_info(THD* thd, MASTER_INFO* mi) pthread_mutex_unlock(&mi->data_lock); if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length())) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } diff --git a/sql/slave.h b/sql/slave.h index 46fe58e1976..e0383b6ebe8 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -474,8 +474,8 @@ int fetch_master_table(THD* thd, const char* db_name, const char* table_name, void table_rule_ent_hash_to_str(String* s, HASH* h); void table_rule_ent_dynamic_array_to_str(String* s, DYNAMIC_ARRAY* a); -int show_master_info(THD* thd, MASTER_INFO* mi); -int show_binlog_info(THD* thd); +bool show_master_info(THD* thd, MASTER_INFO* mi); +bool show_binlog_info(THD* thd); /* See if the query uses any tables that should not be replicated */ int tables_ok(THD* thd, TABLE_LIST* tables); diff --git a/sql/sp.cc b/sql/sp.cc index 6475b64eb18..2fae2addf2a 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -983,7 +983,7 @@ sp_cache_functions(THD *thd, LEX *lex) { delete newlex; thd->lex= oldlex; - net_printf(thd, ER_SP_DOES_NOT_EXIST, "FUNCTION", ls->str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", ls->str); ret= 1; break; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 6a17bc189c3..1f1cf8ac4cd 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -494,16 +494,17 @@ sp_head::execute(THD *thd) case SP_HANDLER_CONTINUE: ctx->save_variables(hf); ctx->push_hstack(ip); - // Fall through + // Fall through default: ip= hip; ret= 0; ctx->clear_handler(); ctx->in_handler= TRUE; + thd->clear_error(); continue; } } - } while (ret == 0 && !thd->killed && !thd->query_error); + } while (ret == 0 && !thd->killed); cleanup_items(thd->current_arena->free_list); thd->current_arena= old_arena; @@ -512,7 +513,7 @@ sp_head::execute(THD *thd) DBUG_PRINT("info", ("ret=%d killed=%d query_error=%d", ret, thd->killed, thd->query_error)); - if (thd->killed || thd->query_error) + if (thd->killed) ret= -1; /* If the DB has changed, the pointer has changed too, but the original thd->db will then have been freed */ @@ -622,8 +623,8 @@ sp_head::execute_procedure(THD *thd, List *args) if (args->elements != params) { - net_printf(thd, ER_SP_WRONG_NO_OF_ARGS, "PROCEDURE", m_name.str, - params, args->elements); + my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), + "PROCEDURE", m_name.str, params, args->elements); DBUG_RETURN(-1); } @@ -694,13 +695,7 @@ sp_head::execute_procedure(THD *thd, List *args) if (! ret) ret= execute(thd); - // Don't copy back OUT values if we got an error - if (ret) - { - if (thd->net.report_error) - send_error(thd, 0, NullS); - } - else if (csize > 0) + if (!ret && csize > 0) { List_iterator_fast li(*args); Item *it; @@ -898,7 +893,7 @@ sp_head::check_backpatch(THD *thd) { if (bp->lab->type == SP_LAB_REF) { - net_printf(thd, ER_SP_LILABEL_MISMATCH, "GOTO", bp->lab->name); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name); return -1; } } diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 169c9809383..3f9ab39e358 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -148,7 +148,7 @@ sp_cursor::pre_open(THD *thd) { if (m_isopen) { - send_error(thd, ER_SP_CURSOR_ALREADY_OPEN); + my_error(ER_SP_CURSOR_ALREADY_OPEN, MYF(0)); return NULL; } @@ -182,7 +182,7 @@ sp_cursor::close(THD *thd) { if (! m_isopen) { - send_error(thd, ER_SP_CURSOR_NOT_OPEN); + my_error(ER_SP_CURSOR_NOT_OPEN, MYF(0)); return -1; } destroy(); @@ -212,12 +212,12 @@ sp_cursor::fetch(THD *thd, List *vars) if (! m_isopen) { - send_error(thd, ER_SP_CURSOR_NOT_OPEN); + my_error(ER_SP_CURSOR_NOT_OPEN, MYF(0)); return -1; } if (m_current_row == NULL) { - send_error(thd, ER_SP_FETCH_NO_DATA); + my_error(ER_SP_FETCH_NO_DATA, MYF(0)); return -1; } @@ -229,7 +229,7 @@ sp_cursor::fetch(THD *thd, List *vars) if (fldcount >= m_prot->get_field_count()) { - send_error(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS); + my_error(ER_SP_WRONG_NO_OF_FETCH_ARGS, MYF(0)); return -1; } s= row[fldcount]; @@ -255,7 +255,7 @@ sp_cursor::fetch(THD *thd, List *vars) } if (fldcount < m_prot->get_field_count()) { - send_error(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS); + my_error(ER_SP_WRONG_NO_OF_FETCH_ARGS, MYF(0)); return -1; } m_current_row= m_current_row->next; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 51768922f6d..bb5f1d0949d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1225,8 +1225,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, { if (!initialized) { - net_printf(thd,ER_OPTION_PREVENTS_STATEMENT, - "--skip-grant-tables"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); return(1); } if (!thd->slave_thread && @@ -1238,16 +1237,14 @@ bool check_change_password(THD *thd, const char *host, const char *user, } if (!thd->slave_thread && !thd->user[0]) { - send_error(thd, ER_PASSWORD_ANONYMOUS_USER); + my_error(ER_PASSWORD_ANONYMOUS_USER, MYF(0)); return(1); } uint len=strlen(new_password); if (len && len != SCRAMBLED_PASSWORD_CHAR_LENGTH && len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { - net_printf(thd, 0, - "Password hash should be a %d-digit hexadecimal number", - SCRAMBLED_PASSWORD_CHAR_LENGTH); + my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); return -1; } return(0); @@ -1285,7 +1282,7 @@ bool change_password(THD *thd, const char *host, const char *user, if (!(acl_user= find_acl_user(host, user))) { VOID(pthread_mutex_unlock(&acl_cache->lock)); - send_error(thd, ER_PASSWORD_NO_MATCH); + my_error(ER_PASSWORD_NO_MATCH, MYF(0)); DBUG_RETURN(1); } /* update loaded acl entry: */ @@ -1298,7 +1295,6 @@ bool change_password(THD *thd, const char *host, const char *user, new_password, new_password_len)) { VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */ - send_error(thd,0); /* purecov: deadcode */ DBUG_RETURN(1); /* purecov: deadcode */ } @@ -2290,11 +2286,11 @@ table_error: revoke_grant Set to 1 if this is a REVOKE command RETURN - 0 ok - 1 error + FALSE ok + TRUE error */ -int mysql_table_grant(THD *thd, TABLE_LIST *table_list, +bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, List &user_list, List &columns, ulong rights, bool revoke_grant) @@ -2311,12 +2307,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); /* purecov: inspected */ - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } if (rights & ~TABLE_ACLS) { my_error(ER_ILLEGAL_GRANT_FOR_TABLE,MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (columns.elements && !revoke_grant) @@ -2325,8 +2321,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, List_iterator column_iter(columns); int res; - if ((res= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(res); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); while ((column = column_iter++)) { @@ -2338,7 +2334,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { my_error(ER_BAD_FIELD_ERROR, MYF(0), column->column.c_ptr(), table_list->alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } column_priv|= column->rights; } @@ -2353,7 +2349,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (access(buf,F_OK)) { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } @@ -2386,19 +2382,19 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, */ tables[0].updating= tables[1].updating= tables[2].updating= 1; if (!tables_ok(0, tables)) - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } #endif if (simple_open_n_lock_tables(thd,tables)) { // Should never happen close_thread_tables(thd); /* purecov: deadcode */ - DBUG_RETURN(-1); /* purecov: deadcode */ + DBUG_RETURN(TRUE); /* purecov: deadcode */ } if (!revoke_grant) create_new_users= test_if_create_new_users(thd); - int result=0; + bool result= FALSE; rw_wrlock(&LOCK_grant); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); my_pthread_setspecific_ptr(THR_MALLOC,&memex); @@ -2411,7 +2407,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, Str->user.length > USERNAME_LENGTH) { my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); - result= -1; + result= TRUE; continue; } /* Create user if needed */ @@ -2421,7 +2417,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, pthread_mutex_unlock(&acl_cache->lock); if (error) { - result= -1; // Remember error + result= TRUE; // Remember error continue; // Add next user } @@ -2441,7 +2437,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), Str->user.str, Str->host.str, table_list->real_name); - result= -1; + result= TRUE; continue; } grant_table = new GRANT_TABLE (Str->host.str, db_name, @@ -2450,7 +2446,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, column_priv); if (!grant_table) // end of memory { - result= -1; /* purecov: deadcode */ + result= TRUE; /* purecov: deadcode */ continue; /* purecov: deadcode */ } my_hash_insert(&column_priv_hash,(byte*) grant_table); @@ -2494,7 +2490,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, db_name, real_name, rights, column_priv, revoke_grant)) { // Crashend table ?? - result= -1; /* purecov: deadcode */ + result= TRUE; /* purecov: deadcode */ } else if (tables[2].table) { @@ -2503,7 +2499,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, db_name, real_name, rights, revoke_grant))) { - result= -1; + result= TRUE; } } } @@ -2517,8 +2513,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } -int mysql_grant(THD *thd, const char *db, List &list, - ulong rights, bool revoke_grant) +bool mysql_grant(THD *thd, const char *db, List &list, + ulong rights, bool revoke_grant) { List_iterator str_list (list); LEX_USER *Str; @@ -2530,7 +2526,7 @@ int mysql_grant(THD *thd, const char *db, List &list, { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); /* purecov: tested */ - DBUG_RETURN(-1); /* purecov: tested */ + DBUG_RETURN(TRUE); /* purecov: tested */ } if (lower_case_table_names && db) @@ -2561,14 +2557,14 @@ int mysql_grant(THD *thd, const char *db, List &list, */ tables[0].updating= tables[1].updating= 1; if (!tables_ok(0, tables)) - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } #endif if (simple_open_n_lock_tables(thd,tables)) { // This should never happen close_thread_tables(thd); /* purecov: deadcode */ - DBUG_RETURN(-1); /* purecov: deadcode */ + DBUG_RETURN(TRUE); /* purecov: deadcode */ } if (!revoke_grant) @@ -2880,11 +2876,11 @@ err: command= "create view"; else if (want_access & SHOW_VIEW_ACL) command= "show create view"; - net_printf(thd,ER_TABLEACCESS_DENIED_ERROR, - command, - thd->priv_user, - thd->host_or_ip, - table ? table->real_name : "unknown"); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + table ? table->real_name : "unknown"); } DBUG_RETURN(1); } @@ -3146,7 +3142,7 @@ static uint command_lengths[]= Send to client grant-like strings depicting user@host privileges */ -int mysql_show_grants(THD *thd,LEX_USER *lex_user) +bool mysql_show_grants(THD *thd,LEX_USER *lex_user) { ulong want_access; uint counter,index; @@ -3161,7 +3157,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!initialized) { my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!lex_user->host.str) @@ -3173,7 +3169,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) lex_user->user.length > USERNAME_LENGTH) { my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } for (counter=0 ; counter < acl_users.elements ; counter++) @@ -3192,7 +3188,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) { my_error(ER_NONEXISTING_GRANT, MYF(0), lex_user->user.str, lex_user->host.str); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } Item_string *field=new Item_string("",0,&my_charset_latin1); @@ -3204,7 +3200,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) field_list.push_back(field); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -3526,7 +3522,7 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) if (!initialized) { - net_printf(thd,ER_OPTION_PREVENTS_STATEMENT, "--skip-grant-tables"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-grant-tables"); DBUG_RETURN(-1); } @@ -3595,7 +3591,7 @@ ACL_USER *check_acl_user(LEX_USER *user_name, } -int mysql_drop_user(THD *thd, List &list) +bool mysql_drop_user(THD *thd, List &list) { uint counter, acl_userd; int result; @@ -3606,7 +3602,7 @@ int mysql_drop_user(THD *thd, List &list) DBUG_ENTER("mysql_drop_user"); if ((result= open_grant_tables(thd, tables))) - DBUG_RETURN(result == 1 ? 0 : 1); + DBUG_RETURN(result != 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -3694,7 +3690,7 @@ int mysql_drop_user(THD *thd, List &list) record[0]))) { tables[0].table->file->print_error(error, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } delete_dynamic_element(&acl_users, acl_userd); } @@ -3708,7 +3704,7 @@ int mysql_drop_user(THD *thd, List &list) DBUG_RETURN(result); } -int mysql_revoke_all(THD *thd, List &list) +bool mysql_revoke_all(THD *thd, List &list) { uint counter; int result; @@ -3717,7 +3713,7 @@ int mysql_revoke_all(THD *thd, List &list) DBUG_ENTER("mysql_revoke_all"); if ((result= open_grant_tables(thd, tables))) - DBUG_RETURN(result == 1 ? 0 : 1); + DBUG_RETURN(result != 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 390106c1546..f6074da5279 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -158,11 +158,11 @@ bool check_change_password(THD *thd, const char *host, const char *user, char *password); bool change_password(THD *thd, const char *host, const char *user, char *password); -int mysql_grant(THD *thd, const char *db, List &user_list, - ulong rights, bool revoke); -int mysql_table_grant(THD *thd, TABLE_LIST *table, List &user_list, - List &column_list, ulong rights, - bool revoke); +bool mysql_grant(THD *thd, const char *db, List &user_list, + ulong rights, bool revoke); +bool mysql_table_grant(THD *thd, TABLE_LIST *table, List &user_list, + List &column_list, ulong rights, + bool revoke); my_bool grant_init(THD *thd); void grant_free(void); void grant_reload(THD *thd); @@ -179,11 +179,11 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table); ulong get_column_grant(THD *thd, GRANT_INFO *grant, const char *db_name, const char *table_name, const char *field_name); -int mysql_show_grants(THD *thd, LEX_USER *user); +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); -int mysql_drop_user(THD *thd, List &list); -int mysql_revoke_all(THD *thd, List &list); +bool mysql_drop_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_base.cc b/sql/sql_base.cc index 8199c6fcdce..9a45660c45b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1815,21 +1815,20 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) tables - list of tables for open&locking RETURN - 0 - ok - -1 - error - 1 - error reported to user + FALSE - ok + TRUE - error NOTE The lock will automaticly be freed by close_thread_tables() */ -int open_and_lock_tables(THD *thd, TABLE_LIST *tables) +bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("open_and_lock_tables"); uint counter; if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter) || mysql_handle_derived(thd->lex)) - DBUG_RETURN(thd->net.report_error ? -1 : 1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ /* Let us propagate pointers to open tables from global table list to table lists in particular selects if needed. @@ -1850,7 +1849,7 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) } } } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -2609,9 +2608,9 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, ** Check that all given fields exists and fill struct with current data ****************************************************************************/ -int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, - List &fields, bool set_query_id, - List *sum_func_list, bool allow_sum_func) +bool setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, + List &fields, bool set_query_id, + List *sum_func_list, bool allow_sum_func) { reg2 Item *item; List_iterator it(fields); @@ -2629,7 +2628,7 @@ int setup_fields(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, (item= *(it.ref()))->check_cols(1)) { select_lex->no_wrap_view_item= 0; - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } if (ref) *(ref++)= item; @@ -2958,7 +2957,6 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name); err: - send_error(thd); DBUG_RETURN(1); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 392534492df..a543222a4a1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -762,7 +762,7 @@ select_result::select_result() void select_result::send_error(uint errcode,const char *err) { - ::send_error(thd, errcode, err); + my_message(errcode, err, MYF(0)); } @@ -865,7 +865,7 @@ bool select_send::send_eof() void select_to_file::send_error(uint errcode,const char *err) { - ::send_error(thd,errcode,err); + my_message(errcode, err, MYF(0)); if (file > 0) { (void) end_io_cache(&cache); diff --git a/sql/sql_class.h b/sql/sql_class.h index 32f156fbee8..f014a597169 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1112,6 +1112,7 @@ public: net.last_error[0]= 0; net.last_errno= 0; net.report_error= 0; + query_error= 0; } inline bool vio_ok() const { return net.vio != 0; } #else diff --git a/sql/sql_db.cc b/sql/sql_db.cc index f41e03b0602..df3c27b9b72 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -379,13 +379,13 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) In this case the entry should not be logged. RETURN VALUES - 0 ok - -1 Error + FALSE ok + TRUE Error */ -int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, - bool silent) +bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, + bool silent) { char path[FN_REFLEN+16]; long result= 1; @@ -489,7 +489,7 @@ exit2: /* db-name is already validated when we come here */ -int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) +bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) { char path[FN_REFLEN+16]; long result=1; @@ -532,7 +532,7 @@ exit: start_waiting_global_read_lock(thd); exit2: VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); - DBUG_RETURN(error ? -1 : 0); /* -1 to delegate send_error() */ + DBUG_RETURN(error); } @@ -548,11 +548,11 @@ exit2: silent Don't generate errors RETURN - 0 ok (Database dropped) - -1 Error generated + FALSE ok (Database dropped) + ERROR Error */ -int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) +bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { long deleted=0; int error= 0; @@ -985,12 +985,12 @@ bool mysql_change_db(THD *thd, const char *name) if (!dbname || !(db_length= strlen(dbname))) { x_free(dbname); /* purecov: inspected */ - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ + my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (check_db_name(dbname)) { - net_printf(thd, ER_WRONG_DB_NAME, dbname); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); x_free(dbname); DBUG_RETURN(1); } @@ -1003,10 +1003,10 @@ bool mysql_change_db(THD *thd, const char *name) thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - net_printf(thd,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->priv_host, @@ -1021,7 +1021,7 @@ bool mysql_change_db(THD *thd, const char *name) path[length-1]=0; // remove ending '\' if (access(path,F_OK)) { - net_printf(thd,ER_BAD_DB_ERROR,dbname); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index f9dba49d2e3..54c6cd1ebc5 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -29,8 +29,8 @@ #include "sp_head.h" #include "sql_trigger.h" -int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, - ha_rows limit, ulong options) +bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, + SQL_LIST *order, ha_rows limit, ulong options) { int error; TABLE *table; @@ -41,22 +41,22 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, ha_rows deleted; DBUG_ENTER("mysql_delete"); - if ((error= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(error); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; table->map=1; - if ((error= mysql_prepare_delete(thd, table_list, &conds))) - DBUG_RETURN(error); + if (mysql_prepare_delete(thd, table_list, &conds)) + DBUG_RETURN(TRUE); const_cond= (!conds || conds->const_item()); safe_update=test(thd->options & OPTION_SAFE_UPDATES); if (safe_update && const_cond) { - send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); - DBUG_RETURN(1); + my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); + DBUG_RETURN(TRUE); } if (thd->lex->duplicates == DUP_IGNORE) @@ -85,7 +85,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, table->quick_keys.clear_all(); // Can't use 'only index' select=make_select(table,0,0,conds,&error); if (error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if ((select && select->check_quick(thd, safe_update, limit)) || !limit) { delete select; @@ -103,8 +103,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, { delete select; free_underlaid_joins(thd, &thd->lex->select_lex); - send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); - DBUG_RETURN(1); + my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); + DBUG_RETURN(TRUE); } } if (options & OPTION_QUICK) @@ -135,7 +135,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, { delete select; free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(-1); // This will force out message + DBUG_RETURN(TRUE); } /* Filesort has already found and selected the rows we want to delete, @@ -150,7 +150,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, { delete select; free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(-1); // This will force out message + DBUG_RETURN(TRUE); } init_read_record(&info,thd,table,select,1,1); deleted=0L; @@ -253,15 +253,13 @@ cleanup: thd->lock=0; } free_underlaid_joins(thd, &thd->lex->select_lex); - if (error >= 0 || thd->net.report_error) - send_error(thd,thd->killed_errno()); - else + if (error < 0) { thd->row_count_func= deleted; send_ok(thd,deleted); DBUG_PRINT("info",("%d records deleted",deleted)); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -275,11 +273,10 @@ cleanup: conds - conditions RETURN VALUE - 0 - OK - 1 - error (message is sent to user) - -1 - error (message is not sent to user) + FALSE OK + TRUE error */ -int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) +bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) { SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_prepare_delete"); @@ -287,19 +284,19 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) if (setup_tables(thd, table_list, conds) || setup_conds(thd, table_list, conds) || setup_ftfuncs(select_lex)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (!table_list->updatable || check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (unique_table(table_list, table_list->next_independent())) { my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, conds); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -323,16 +320,15 @@ extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b) thd thread handler RETURN - 0 OK - -1 Error + FALSE OK + TRUE Error */ -int mysql_multi_delete_prepare(THD *thd) +bool mysql_multi_delete_prepare(THD *thd) { LEX *lex= thd->lex; TABLE_LIST *aux_tables= (TABLE_LIST *)lex->auxilliary_table_list.first; TABLE_LIST *target_tbl; - int res= 0; DBUG_ENTER("mysql_multi_delete_prepare"); /* @@ -342,7 +338,7 @@ int mysql_multi_delete_prepare(THD *thd) lex->query_tables also point on local list of DELETE SELECT_LEX */ if (setup_tables(thd, lex->query_tables, &lex->select_lex.where)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Fix tables-to-be-deleted-from list to point at opened tables */ for (target_tbl= (TABLE_LIST*) aux_tables; @@ -355,7 +351,7 @@ int mysql_multi_delete_prepare(THD *thd) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), target_tbl->real_name, "DELETE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* Check are deleted table used somewhere inside subqueries. @@ -373,12 +369,11 @@ int mysql_multi_delete_prepare(THD *thd) { my_error(ER_UPDATE_TABLE_USED, MYF(0), target_tbl->correspondent_table->real_name); - res= -1; - break; + DBUG_RETURN(TRUE); } } } - DBUG_RETURN(res); + DBUG_RETURN(FALSE); } @@ -522,7 +517,7 @@ void multi_delete::send_error(uint errcode,const char *err) DBUG_ENTER("multi_delete::send_error"); /* First send error what ever it is ... */ - ::send_error(thd,errcode,err); + my_message(errcode, err, MYF(0)); /* If nothing deleted return */ if (!deleted) @@ -668,9 +663,7 @@ bool multi_delete::send_eof() if (ha_autocommit_or_rollback(thd,local_error > 0)) local_error=1; - if (local_error) - ::send_error(thd); - else + if (!local_error) { thd->row_count_func= deleted; ::send_ok(thd, deleted); @@ -695,12 +688,12 @@ bool multi_delete::send_eof() - If we want to have a name lock on the table on exit without errors. */ -int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) +bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) { HA_CREATE_INFO create_info; char path[FN_REFLEN]; TABLE **table_ptr; - int error; + bool error; DBUG_ENTER("mysql_truncate"); bzero((char*) &create_info,sizeof(create_info)); @@ -738,7 +731,7 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) { my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!ha_supports_generate(table_type)) { @@ -748,11 +741,11 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) HA_POS_ERROR, 0)); } if (lock_and_wait_for_table_name(thd, table_list)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } *fn_ext(path)=0; // Remove the .frm extension - error= ha_create_table(path,&create_info,1) ? -1 : 0; + error= ha_create_table(path,&create_info,1); query_cache_invalidate3(thd, table_list, 0); end: @@ -779,5 +772,5 @@ end: unlock_table_name(thd, table_list); VOID(pthread_mutex_unlock(&LOCK_open)); } - DBUG_RETURN(error ? -1 : 0); + DBUG_RETURN(error); } diff --git a/sql/sql_do.cc b/sql/sql_do.cc index 25a8359f3d2..3ca3bea743a 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -20,16 +20,16 @@ #include "mysql_priv.h" #include "sql_acl.h" -int mysql_do(THD *thd, List &values) +bool mysql_do(THD *thd, List &values) { List_iterator li(values); Item *value; DBUG_ENTER("mysql_do"); if (setup_fields(thd, 0, 0, values, 0, 0, 0)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); while ((value = li++)) value->val_int(); thd->clear_error(); // DO always is OK send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } diff --git a/sql/sql_error.cc b/sql/sql_error.cc index c0f76ab0388..e4b9e615db6 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -184,14 +184,14 @@ void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level, Takes into account the current LIMIT RETURN VALUES - 0 ok - 1 Error sending data to client + FALSE ok + TRUE Error sending data to client */ static const char *warning_level_names[]= {"Note", "Warning", "Error", "?"}; static int warning_level_length[]= { 4, 7, 5, 1 }; -my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) +bool mysqld_show_warnings(THD *thd, ulong levels_to_show) { List field_list; DBUG_ENTER("mysqld_show_warnings"); @@ -202,7 +202,7 @@ my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) if (thd->protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); MYSQL_ERROR *err; SELECT_LEX *sel= &thd->lex->select_lex; @@ -226,10 +226,10 @@ my_bool mysqld_show_warnings(THD *thd, ulong levels_to_show) protocol->store((uint32) err->code); protocol->store(err->msg, strlen(err->msg), system_charset_info); if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if (!--limit) break; } - send_eof(thd); - DBUG_RETURN(0); + send_eof(thd); + DBUG_RETURN(FALSE); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 1443f9f9d5f..bb872b2c39b 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -47,7 +47,7 @@ static TABLE **find_table_ptr_by_name(THD *thd,const char *db, bool is_alias, bool dont_lock, bool *was_flushed); -int mysql_ha_open(THD *thd, TABLE_LIST *tables) +bool mysql_ha_open(THD *thd, TABLE_LIST *tables) { HANDLER_TABLES_HACK(thd); uint counter; @@ -58,18 +58,18 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) HANDLER_TABLES_HACK(thd); if (err) - return -1; + return TRUE; // there can be only one table in *tables if (!(tables->table->file->table_flags() & HA_CAN_SQL_HANDLER)) { my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->alias); mysql_ha_close(thd, tables,1); - return -1; + return TRUE; } send_ok(thd); - return 0; + return FALSE; } @@ -98,11 +98,11 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables) is suppressed. RETURN - 0 ok - -1 error + FALSE OK + TRUE Error */ -int mysql_ha_close(THD *thd, TABLE_LIST *tables, +bool mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok, bool dont_lock, bool no_alias) { TABLE **table_ptr; @@ -127,11 +127,11 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, { my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), tables->alias, "HANDLER"); - return -1; + return TRUE; } if (!dont_send_ok) send_ok(thd); - return 0; + return FALSE; } @@ -201,11 +201,11 @@ static enum enum_ha_read_modes rkey_to_rnext[]= { RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV }; -int mysql_ha_read(THD *thd, TABLE_LIST *tables, - enum enum_ha_read_modes mode, char *keyname, - List *key_expr, - enum ha_rkey_function ha_rkey_mode, Item *cond, - ha_rows select_limit,ha_rows offset_limit) +bool mysql_ha_read(THD *thd, TABLE_LIST *tables, + enum enum_ha_read_modes mode, char *keyname, + List *key_expr, + enum ha_rkey_function ha_rkey_mode, Item *cond, + ha_rows select_limit,ha_rows offset_limit) { int err, keyno=-1; bool was_flushed; @@ -216,12 +216,12 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, { my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0), tables->alias,"HANDLER"); - return -1; + return TRUE; } tables->table=table; if (cond && (cond->fix_fields(thd, tables, &cond) || cond->check_cols(1))) - return -1; + return TRUE; /* InnoDB needs to know that this table handle is used in the HANDLER */ @@ -233,7 +233,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, { my_printf_error(ER_KEY_DOES_NOT_EXITS,ER(ER_KEY_DOES_NOT_EXITS),MYF(0), keyname,tables->alias); - return -1; + return TRUE; } table->file->ha_index_or_rnd_end(); table->file->ha_index_init(keyno); @@ -333,10 +333,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, key_len+=key_part->store_length; } if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len)))) - { - send_error(thd,ER_OUTOFMEMORY); goto err; - } key_copy(key, table, keyno, key_len); err=table->file->index_read(table->record[0], key,key_len,ha_rkey_mode); @@ -344,7 +341,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, break; } default: - send_error(thd,ER_ILLEGAL_HA); + my_error(ER_ILLEGAL_HA, MYF(0)); goto err; } @@ -384,11 +381,11 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, ok: mysql_unlock_tables(thd,lock); send_eof(thd); - return 0; + return FALSE; err: mysql_unlock_tables(thd,lock); err0: - return -1; + return TRUE; } diff --git a/sql/sql_help.cc b/sql/sql_help.cc index cba74c93a6a..d108f6f69b4 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -276,7 +276,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, (iindex_relations= find_type((char*) primary_key_name, &relations->keynames, 1+2)-1)<0) { - send_error(thd,ER_CORRUPT_HELP_DB); + my_error(ER_CORRUPT_HELP_DB, 0); DBUG_RETURN(-1); } rtopic_id= find_fields[help_relation_help_topic_id].field; @@ -607,12 +607,11 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, thd Thread handler RETURN VALUES - 0 Success - 1 Error and send_error already commited - -1 error && send_error should be issued (normal case) + FALSE Success + TRUE Error and send_error already commited */ -int mysqld_help(THD *thd, const char *mask) +bool mysqld_help(THD *thd, const char *mask) { Protocol *protocol= thd->protocol; SQL_SELECT *select; @@ -640,8 +639,8 @@ int mysqld_help(THD *thd, const char *mask) uint mlen= strlen(mask); MEM_ROOT *mem_root= &thd->mem_root; - if ((res= open_and_lock_tables(thd, tables))) - goto end; + if (open_and_lock_tables(thd, tables)) + goto error; /* Init tables and fields to be usable from items @@ -650,10 +649,7 @@ int mysqld_help(THD *thd, const char *mask) setup_tables(thd, tables, 0); memcpy((char*) used_fields, (char*) init_used_fields, sizeof(used_fields)); if (init_fields(thd, tables, used_fields, array_elements(used_fields))) - { - res= -1; - goto end; - } + goto error; size_t i; for (i=0; ifile->init_table_handle_for_HANDLER(); @@ -661,12 +657,8 @@ int mysqld_help(THD *thd, const char *mask) if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[0].table, used_fields[help_topic_name].field,&error))) - { - res= -1; - goto end; - } + goto error; - res= 1; count_topics= search_topics(thd,tables[0].table,used_fields, select,&topics_list, &name, &description, &example); @@ -678,10 +670,8 @@ int mysqld_help(THD *thd, const char *mask) if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[3].table, used_fields[help_keyword_name].field,&error))) - { - res= -1; - goto end; - } + goto error; + count_topics=search_keyword(thd,tables[3].table,used_fields,select,&key_id); delete select; count_topics= (count_topics != 1) ? 0 : @@ -697,10 +687,7 @@ int mysqld_help(THD *thd, const char *mask) if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[1].table, used_fields[help_category_name].field,&error))) - { - res= -1; - goto end; - } + goto error; count_categories= search_categories(thd, tables[1].table, used_fields, select, @@ -709,13 +696,13 @@ int mysqld_help(THD *thd, const char *mask) if (!count_categories) { if (send_header_2(protocol,FALSE)) - goto end; + goto error; } else if (count_categories > 1) { if (send_header_2(protocol,FALSE) || send_variant_2_list(mem_root,protocol,&categories_list,"Y",0)) - goto end; + goto error; } else { @@ -728,20 +715,14 @@ int mysqld_help(THD *thd, const char *mask) new Item_int((int32)category_id)); if (!(select= prepare_simple_select(thd,cond_topic_by_cat, tables,tables[0].table,&error))) - { - res= -1; - goto end; - } + goto error; get_all_items_for_category(thd,tables[0].table, used_fields[help_topic_name].field, select,&topics_list); delete select; if (!(select= prepare_simple_select(thd,cond_cat_by_cat,tables, tables[1].table,&error))) - { - res= -1; - goto end; - } + goto error; get_all_items_for_category(thd,tables[1].table, used_fields[help_category_name].field, select,&subcategories_list); @@ -750,39 +731,36 @@ int mysqld_help(THD *thd, const char *mask) if (send_header_2(protocol, true) || send_variant_2_list(mem_root,protocol,&topics_list, "N",cat) || send_variant_2_list(mem_root,protocol,&subcategories_list,"Y",cat)) - goto end; + goto error; } } else if (count_topics == 1) { if (send_answer_1(protocol,&name,&description,&example)) - goto end; + goto error; } else { /* First send header and functions */ if (send_header_2(protocol, FALSE) || send_variant_2_list(mem_root,protocol, &topics_list, "N", 0)) - goto end; + goto error; if (!(select= prepare_select_for_name(thd,mask,mlen,tables,tables[1].table, used_fields[help_category_name].field,&error))) - { - res= -1; - goto end; - } + goto error; search_categories(thd, tables[1].table, used_fields, select,&categories_list, 0); delete select; /* Then send categories */ if (send_variant_2_list(mem_root,protocol, &categories_list, "Y", 0)) - goto end; + goto error; } - res= 0; - send_eof(thd); end: - DBUG_RETURN(res); + DBUG_RETURN(FALSE); +error: + DBUG_RETURN(TRUE); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 787774e3236..04d7bf5d5ab 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -115,12 +115,12 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, } -int mysql_insert(THD *thd,TABLE_LIST *table_list, - List &fields, - List &values_list, - List &update_fields, - List &update_values, - enum_duplicates duplic) +bool mysql_insert(THD *thd,TABLE_LIST *table_list, + List &fields, + List &values_list, + List &update_fields, + List &update_values, + enum_duplicates duplic) { int error, res; /* @@ -174,7 +174,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, my_printf_error(ER_DELAYED_INSERT_TABLE_LOCKED, ER(ER_DELAYED_INSERT_TABLE_LOCKED), MYF(0), table_list->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } if ((table= delayed_get_table(thd,table_list)) && !thd->is_fatal_error) @@ -200,7 +200,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, #endif /* EMBEDDED_LIBRARY */ res= open_and_lock_tables(thd, table_list); if (res || thd->is_fatal_error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); table= table_list->table; thd->proc_info="init"; @@ -298,6 +298,15 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, info.records++; continue; } + /* + Field::store methods can't send errors + + TODO: set thd->abort_on_warning if values_list.elements == 1 + and check that all items return warning in case of problem with + storing field. + */ + if (!thd->net.report_error) + my_error(ER_UNKNOWN_ERROR, MYF(0)); error=1; break; } @@ -315,6 +324,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, info.records++; continue; } + /* Field::store methods can't send errors */ + if (!thd->net.report_error) + my_error(ER_UNKNOWN_ERROR, MYF(0)); error=1; break; } @@ -465,7 +477,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; thd->abort_on_warning= 0; - DBUG_RETURN(0); + DBUG_RETURN(FALSE); abort: #ifndef EMBEDDED_LIBRARY @@ -475,7 +487,7 @@ abort: free_underlaid_joins(thd, &thd->lex->select_lex); table->insert_values=0; thd->abort_on_warning= 0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } @@ -609,11 +621,11 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, table_list Global/local table list RETURN VALUE - 0 OK - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, +bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, List &fields, List_item *values, List &update_fields, List &update_values, enum_duplicates duplic) @@ -621,7 +633,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, bool insert_into_view= (table_list->view != 0); /* TODO: use this condition for 'WITH CHECK OPTION' */ Item *unused_conds= 0; - int res; + bool res; DBUG_ENTER("mysql_prepare_insert"); if (mysql_prepare_insert_check_table(thd, table_list, fields, &unused_conds)) @@ -636,15 +648,15 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, thd->lex->select_lex.no_wrap_view_item= 0, res) || setup_fields(thd, 0, table_list, update_values, 0, 0, 0)))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (unique_table(table_list, table_list->next_independent())) { my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } thd->lex->select_lex.first_execution= 0; - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -737,7 +749,12 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) store_record(table,insert_values); restore_record(table,record[1]); if (fill_record(*info->update_fields, *info->update_values, 0)) + { + /* Field::store methods can't send errors */ + if (!thd->net.report_error) + my_error(ER_UNKNOWN_ERROR, MYF(0)); goto err; + } /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ if (info->view && @@ -1018,7 +1035,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list) delete tmp; thd->fatal_error(); pthread_mutex_unlock(&LOCK_delayed_create); - net_printf(thd,ER_CANT_CREATE_THREAD,error); + my_error(ER_CANT_CREATE_THREAD, MYF(0), error); DBUG_RETURN(0); } @@ -1648,11 +1665,11 @@ bool delayed_insert::handle_inserts(void) thd thread handler RETURN - 0 OK - -1 Error + FALSE OK + TRUE Error */ -int mysql_insert_select_prepare(THD *thd) +bool mysql_insert_select_prepare(THD *thd) { LEX *lex= thd->lex; DBUG_ENTER("mysql_insert_select_prepare"); @@ -1664,8 +1681,8 @@ int mysql_insert_select_prepare(THD *thd) if (mysql_prepare_insert_check_table(thd, lex->query_tables, lex->field_list, &lex->select_lex.where)) - DBUG_RETURN(-1); - DBUG_RETURN(0); + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); } @@ -1768,8 +1785,7 @@ void select_insert::send_error(uint errcode,const char *err) { DBUG_ENTER("select_insert::send_error"); - /* TODO error should be sent at the query processing end */ - ::send_error(thd,errcode,err); + my_message(errcode, err, MYF(0)); if (!table) { @@ -1845,8 +1861,6 @@ bool select_insert::send_eof() if (error) { table->file->print_error(error,MYF(0)); - //TODO error should be sent at the query processing end - ::send_error(thd); DBUG_RETURN(1); } char buff[160]; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 72d28aa4526..8536bcb5c3e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -328,8 +328,8 @@ protected: TABLE *table; /* temporary table using for appending UNION results */ select_result *result; - int res; ulong found_rows_for_union; + bool res; bool prepared, // prepare phase already performed for UNION (unit) optimized, // optimize phase already performed for UNION (unit) executed, // already executed @@ -388,9 +388,9 @@ public: void exclude_tree(); /* UNION methods */ - int prepare(THD *thd, select_result *result, ulong additional_options); - int exec(); - int cleanup(); + bool prepare(THD *thd, select_result *result, ulong additional_options); + bool exec(); + bool cleanup(); inline void unclean() { cleaned= 0; } void reinit_exec_mechanism(); @@ -398,7 +398,7 @@ public: void print(String *str); ulong init_prepare_fake_select_lex(THD *thd); - int change_result(select_subselect *result, select_subselect *old_result); + bool change_result(select_subselect *result, select_subselect *old_result); void set_limit(st_select_lex *values, st_select_lex *sl); friend void mysql_init_query(THD *thd, uchar *buf, uint length, bool lexonly); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 28de2b9d116..353a3b2c83c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -78,7 +78,7 @@ static int read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, List &fields, READ_INFO &read_info, String &enclosed, ulong skip_lines); -int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, +bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, List &fields, enum enum_duplicates handle_duplicates, bool read_file_from_client,thr_lock_type lock_type) { @@ -112,16 +112,16 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { my_message(ER_WRONG_FIELD_TERMINATORS,ER(ER_WRONG_FIELD_TERMINATORS), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } table_list->lock_type= lock_type; - if ((res= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(res); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); /* TODO: add key check when we will support VIEWs in LOAD */ if (!table_list->updatable) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } table= table_list->table; transactional_table= table->file->has_transactions(); @@ -140,14 +140,14 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, Item *unused_conds= 0; if (setup_tables(thd, table_list, &unused_conds) || setup_fields(thd, 0, table_list, fields, 1, 0, 0)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (thd->dupp_field) { my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (check_that_all_fields_are_given_values(thd, table)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } uint tot_length=0; @@ -173,7 +173,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { my_message(ER_BLOBS_AND_NO_TERMINATED,ER(ER_BLOBS_AND_NO_TERMINATED), MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* We can't give an error in the middle when using LOCAL files */ @@ -206,7 +206,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, #if !defined(__WIN__) && !defined(OS2) && ! defined(__NETWARE__) MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(MY_WME))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); // if we are not in slave thread, the file must be: if (!thd->slave_thread && @@ -218,14 +218,14 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, (stat_info.st_mode & S_IFIFO) == S_IFIFO))) { my_error(ER_TEXTFILE_NOT_READABLE,MYF(0),name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) is_fifo = 1; #endif } if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } COPY_INFO info; @@ -240,7 +240,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { if (file >= 0) my_close(file,MYF(0)); // no files in net reading - DBUG_RETURN(-1); // Can't allocate buffers + DBUG_RETURN(TRUE); // Can't allocate buffers } #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_map.cc b/sql/sql_map.cc index e7e24f957c6..c6637474908 100644 --- a/sql/sql_map.cc +++ b/sql/sql_map.cc @@ -47,13 +47,12 @@ mapped_files::mapped_files(const my_string filename,byte *magic,uint magic_lengt 0L))) { error=errno; - my_printf_error(0,"Can't map file: %s, errno: %d",MYF(0), - (my_string) name,error); + my_error(ER_NO_FILE_MAPPING,MYF(0), (my_string) name, error); } } if (map && memcmp(map,magic,magic_length)) { - my_printf_error(0,"Wrong magic in %s",MYF(0),name); + my_error(ER_WRONG_MAGIC, MYF(0), name); VOID(munmap(map,size)); map=0; } @@ -112,8 +111,7 @@ mapped_files *map_file(const my_string name,byte *magic,uint magic_length) { map->use_count++; if (!map->map) - my_printf_error(0,"Can't map file: %s, error: %d",MYF(0),path, - map->error); + my_error(ER_NO_FILE_MAPPING, MYF(0), path, map->error); } VOID(pthread_mutex_unlock(&LOCK_mapped_file)); return map; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f93aaf09933..8817a29a705 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1191,7 +1191,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!db || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); goto err; } if (lower_case_table_names) @@ -1370,8 +1370,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, db= thd->alloc(db_len + tbl_len + 2); tbl_name= strmake(db, packet + 1, db_len)+1; strmake(tbl_name, packet + db_len + 2, tbl_len); - if (mysql_table_dump(thd, db, tbl_name, -1)) - send_error(thd); // dump to NET + mysql_table_dump(thd, db, tbl_name, -1); break; } case COM_CHANGE_USER: @@ -1396,7 +1395,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* Small check for incoming packet */ if ((uint) ((uchar*) db - net->read_pos) > packet_length) { - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); break; } #endif @@ -1418,7 +1417,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!(thd->user= my_strdup(user, MYF(0)))) { thd->user= save_user; - send_error(thd, ER_OUT_OF_RESOURCES); + my_error(ER_OUT_OF_RESOURCES, MYF(0)); break; } @@ -1430,7 +1429,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { /* authentication failure, we shall restore old user */ if (res > 0) - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); x_free(thd->user); thd->user= save_user; thd->priv_user= save_priv_user; @@ -1538,7 +1537,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_FIELD_LIST: // This isn't actually needed #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ break; #else { @@ -1551,7 +1550,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, bzero((char*) &table_list,sizeof(table_list)); if (!(table_list.db=thd->db)) { - send_error(thd,ER_NO_DB_ERROR); + my_error(ER_NO_DB_ERROR, MYF(0)); break; } pend= strend(packet); @@ -1604,7 +1603,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); break; } if (check_access(thd,CREATE_ACL,db,0,1,0)) @@ -1621,14 +1620,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* null test to handle EOM */ if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); break; } if (check_access(thd,DROP_ACL,db,0,1,0)) break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); break; } mysql_log.write(thd,command,db); @@ -1670,9 +1669,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (check_global_access(thd,RELOAD_ACL)) break; mysql_log.write(thd,command,NullS); - if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, NULL)) - send_error(thd, 0); - else + if (!reload_acl_and_cache(thd, options, (TABLE_LIST*) 0, NULL)) send_ok(thd); break; } @@ -1696,7 +1693,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, else if (level != SHUTDOWN_WAIT_ALL_BUFFERS) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level"); - send_error(thd); break; } DBUG_PRINT("quit",("Got shutdown command for level %u", level)); @@ -1780,7 +1776,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, send_eof(thd); break; default: - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); break; } break; @@ -1799,7 +1795,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_DELAYED_INSERT: case COM_END: default: - send_error(thd, ER_UNKNOWN_COM_ERROR); + my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); break; } if (thd->lock || thd->open_tables || thd->derived_tables) @@ -1808,8 +1804,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, close_thread_tables(thd); /* Free tables */ } - if (thd->is_fatal_error) - send_error(thd,0); // End of memory ? + /* report error issued during command execution */ + if (thd->killed_errno() && !thd->net.report_error) + thd->send_kill_message(); + if (thd->is_fatal_error || thd->net.report_error) + send_error(thd); time_t start_of_query=thd->start_time; thd->end_time(); // Set start time @@ -1854,8 +1853,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, query_length RETURN VALUES - 0 ok - 1 error; In this case thd->fatal_error is set + FALSE ok + TRUE error; In this case thd->fatal_error is set */ bool alloc_query(THD *thd, char *packet, ulong packet_length) @@ -1880,7 +1879,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) packet_length, thd->db_length+ 1 + QUERY_CACHE_FLAGS_SIZE))) - return 1; + return TRUE; thd->query[packet_length]=0; thd->query_length= packet_length; @@ -1890,7 +1889,7 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); - return 0; + return FALSE; } /**************************************************************************** @@ -1898,10 +1897,10 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) ** Execute command saved in thd and current_lex->sql_command ****************************************************************************/ -int +bool mysql_execute_command(THD *thd) { - int res= 0; + bool res= FALSE; LEX *lex= thd->lex; /* first table of first SELECT_LEX */ TABLE_LIST *first_table= (TABLE_LIST*) lex->select_lex.table_list.first; @@ -1982,7 +1981,6 @@ mysql_execute_command(THD *thd) if ((tmp= my_tz_get_table_list(thd, &lex->query_tables_last)) == &fake_time_zone_tables_list) { - send_error(thd, 0); DBUG_RETURN(-1); } lex->time_zone_tables_used= tmp; @@ -1998,7 +1996,7 @@ mysql_execute_command(THD *thd) !(thd->slave_thread || (thd->master_access & SUPER_ACL)) && (uc_update_queries[lex->sql_command] > 0)) { - net_printf(thd, ER_OPTION_PREVENTS_STATEMENT, "--read-only"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only"); DBUG_RETURN(-1); } @@ -2027,20 +2025,14 @@ mysql_execute_command(THD *thd) lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, any_db, 0, 0, 0); if (res) - { - res=0; - break; // Error message is given - } + goto error; if (!(res= open_and_lock_tables(thd, all_tables))) { if (lex->describe) { if (!(result= new select_send())) - { - send_error(thd, ER_OUT_OF_RESOURCES); goto error; - } else thd->send_explain_fields(result); res= mysql_explain_union(thd, &thd->lex->unit, result); @@ -2060,10 +2052,7 @@ mysql_execute_command(THD *thd) else { if (!result && !(result= new select_send())) - { - res= -1; - break; - } + goto error; query_cache_store_query(thd, all_tables); res= handle_select(thd, lex, result); if (result != lex->result) @@ -2083,6 +2072,7 @@ mysql_execute_command(THD *thd) CHARSET_INFO *to_cs= thd->variables.collation_connection; bool need_conversion; user_var_entry *entry; + String *pstr= &str; uint32 unused; /* Convert @var contents to string in connection character set. Although @@ -2098,26 +2088,37 @@ mysql_execute_command(THD *thd) String *pstr; my_bool is_var_null; pstr= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC); + /* + NULL value of variable checked early as entry->value so here + we can't get NULL in normal conditions + */ DBUG_ASSERT(!is_var_null); if (!pstr) - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_ASSERT(pstr == &str); + goto error; } else + { + /* + variable absent or equal to NULL, so we need to set variable to + something reasonable to get readable error message during parsing + */ str.set("NULL", 4, &my_charset_latin1); + } + need_conversion= - String::needs_conversion(str.length(), str.charset(), to_cs, &unused); + String::needs_conversion(pstr->length(), pstr->charset(), + to_cs, &unused); - query_len= need_conversion? (str.length() * to_cs->mbmaxlen) : - str.length(); + query_len= need_conversion? (pstr->length() * to_cs->mbmaxlen) : + pstr->length(); if (!(query_str= alloc_root(&thd->mem_root, query_len+1))) - send_error(thd, ER_OUT_OF_RESOURCES); + goto error; if (need_conversion) - query_len= copy_and_convert(query_str, query_len, to_cs, str.ptr(), - str.length(), str.charset()); + query_len= copy_and_convert(query_str, query_len, to_cs, pstr->ptr(), + pstr->length(), pstr->charset()); else - memcpy(query_str, str.ptr(), str.length()); + memcpy(query_str, pstr->ptr(), pstr->length()); query_str[query_len]= 0; } else @@ -2130,8 +2131,8 @@ mysql_execute_command(THD *thd) query_len, query_str)); } thd->command= COM_PREPARE; - if (!mysql_stmt_prepare(thd, query_str, query_len + 1, - &lex->prepared_stmt_name)) + if (!(res= mysql_stmt_prepare(thd, query_str, query_len + 1, + &lex->prepared_stmt_name))) send_ok(thd, 0L, 0L, "Statement prepared"); break; } @@ -2157,22 +2158,20 @@ mysql_execute_command(THD *thd) } else { - res= -1; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), lex->prepared_stmt_name.length, lex->prepared_stmt_name.str, "DEALLOCATE PREPARE"); + goto error; } break; } case SQLCOM_DO: if (all_tables && - ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || - (res= open_and_lock_tables(thd, all_tables)))) - break; + (check_table_access(thd, SELECT_ACL, all_tables, 0) || + open_and_lock_tables(thd, all_tables))) + goto error; res= mysql_do(thd, *lex->insert_list); - if (thd->net.report_error) - res= -1; break; case SQLCOM_EMPTY_QUERY: @@ -2222,12 +2221,12 @@ mysql_execute_command(THD *thd) goto error; /* This query don't work now. See comment in repl_failsafe.cc */ #ifndef WORKING_NEW_MASTER - net_printf(thd, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER"); - res= 1; + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SHOW NEW MASTER"); + goto error; #else res = show_new_master(thd); -#endif break; +#endif } #ifdef HAVE_REPLICATION @@ -2323,7 +2322,7 @@ mysql_execute_command(THD *thd) if (check_global_access(thd, SUPER_ACL)) goto error; if (end_active_trans(thd)) - res= -1; + goto error; else res = load_master_data(thd); break; @@ -2354,7 +2353,7 @@ mysql_execute_command(THD *thd) } if (strlen(first_table->real_name) > NAME_LEN) { - net_printf(thd, ER_WRONG_TABLE_NAME, first_table->real_name); + my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->real_name); break; } pthread_mutex_lock(&LOCK_active_mi); @@ -2381,7 +2380,7 @@ mysql_execute_command(THD *thd) TABLE_LIST *select_tables= lex->query_tables; if ((res= create_table_precheck(thd, select_tables, create_table))) - goto unsent_create_error; + goto create_error; #ifndef HAVE_READLINK lex->create_info.data_file_name=lex->create_info.index_file_name=0; @@ -2391,10 +2390,7 @@ mysql_execute_command(THD *thd) create_table->real_name) || append_file_to_dir(thd, &lex->create_info.index_file_name, create_table->real_name)) - { - res=-1; - goto unsent_create_error; - } + goto create_error; #endif /* If we are using SET CHARSET without DEFAULT, add an implicit @@ -2428,7 +2424,7 @@ mysql_execute_command(THD *thd) if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && unique_table(create_table, select_tables)) { - net_printf(thd, ER_UPDATE_TABLE_USED, create_table->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->real_name); goto create_error; } /* If we create merge table, we have to test tables in merge, too */ @@ -2441,7 +2437,7 @@ mysql_execute_command(THD *thd) { if (unique_table(tab, select_tables)) { - net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), tab->real_name); goto create_error; } } @@ -2488,11 +2484,9 @@ mysql_execute_command(THD *thd) break; create_error: - res= 1; //error reported -unsent_create_error: /* put tables back for PS rexecuting */ lex->link_first_table_back(create_table, link_to_local); - break; + goto error; } case SQLCOM_CREATE_INDEX: DBUG_ASSERT(first_table == all_tables && first_table != 0); @@ -2500,7 +2494,7 @@ unsent_create_error: goto error; /* purecov: inspected */ thd->slow_command=TRUE; if (end_active_trans(thd)) - res= -1; + goto error; else res = mysql_create_index(thd, first_table, lex->key_list); break; @@ -2529,7 +2523,7 @@ unsent_create_error: */ if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); goto error; } { @@ -2543,16 +2537,15 @@ unsent_create_error: case SQLCOM_ALTER_TABLE: DBUG_ASSERT(first_table == all_tables && first_table != 0); #if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else { ulong priv=0; if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { - net_printf(thd, ER_WRONG_TABLE_NAME, lex->name); - res=0; - break; + my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name); + goto error; } if (!select_lex->db) select_lex->db= first_table->db; @@ -2583,7 +2576,7 @@ unsent_create_error: lex->create_info.data_file_name=lex->create_info.index_file_name=0; /* ALTER TABLE ends previous transaction */ if (end_active_trans(thd)) - res= -1; + goto error; else { thd->slow_command=TRUE; @@ -2628,16 +2621,14 @@ unsent_create_error: } } query_cache_invalidate3(thd, first_table, 0); - if (end_active_trans(thd)) - res= -1; - else if (mysql_rename_tables(thd, first_table)) - res= -1; + if (end_active_trans(thd) || mysql_rename_tables(thd, first_table)) + goto error; break; } #ifndef EMBEDDED_LIBRARY case SQLCOM_SHOW_BINLOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else { @@ -2651,7 +2642,7 @@ unsent_create_error: case SQLCOM_SHOW_CREATE: DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else { @@ -2754,8 +2745,6 @@ unsent_create_error: (ORDER *) select_lex->order_list.first, select_lex->select_limit, lex->duplicates); - if (thd->net.report_error) - res= -1; break; case SQLCOM_UPDATE_MULTI: { @@ -2780,8 +2769,6 @@ unsent_create_error: res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values, select_lex->item_list, lex->value_list, (update ? DUP_UPDATE : lex->duplicates)); - if (thd->net.report_error) - res= -1; if (first_table->view && !first_table->contain_auto_increment) thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it break; @@ -2834,11 +2821,9 @@ unsent_create_error: lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; delete result; } - if (thd->net.report_error) - res= -1; } else - res= -1; + res= TRUE; if (first_table->view && !first_table->contain_auto_increment) thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it @@ -2855,7 +2840,7 @@ unsent_create_error: */ if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS); + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); goto error; } @@ -2869,8 +2854,6 @@ unsent_create_error: res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, select_lex->select_limit, select_lex->options); - if (thd->net.report_error) - res= -1; break; } case SQLCOM_DELETE_MULTI: @@ -2888,14 +2871,11 @@ unsent_create_error: if (select_lex->item_list.elements != 0) select_lex->item_list.empty(); if (add_item_to_list(thd, new Item_null())) - { - res= -1; - break; - } + goto error; thd->proc_info="init"; - if ((res= open_and_lock_tables(thd, all_tables))) - break; + if (open_and_lock_tables(thd, all_tables)) + goto error; if ((res= mysql_multi_delete_prepare(thd))) break; @@ -2913,12 +2893,10 @@ unsent_create_error: select_lex->options | thd->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK, result, unit, select_lex); - if (thd->net.report_error) - res= -1; delete result; } else - res= -1; // Error is not sent + res= TRUE; close_thread_tables(thd); break; } @@ -2930,10 +2908,7 @@ unsent_create_error: if (check_table_access(thd, DROP_ACL, all_tables, 0)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) - { - res= -1; - break; - } + goto error; } else { @@ -2957,13 +2932,13 @@ unsent_create_error: if (check_one_table_access(thd, INDEX_ACL, all_tables)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) - res= -1; + goto error; else res = mysql_drop_index(thd, first_table, &lex->alter_info); break; case SQLCOM_SHOW_DATABASES: #if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else if ((specialflag & SPECIAL_SKIP_SHOW_DB) && @@ -3009,7 +2984,7 @@ unsent_create_error: break; case SQLCOM_SHOW_LOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else { @@ -3022,30 +2997,30 @@ unsent_create_error: case SQLCOM_SHOW_TABLES: /* FALL THROUGH */ #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else { char *db=select_lex->db ? select_lex->db : thd->db; if (!db) { - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ + my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: inspected */ goto error; /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' if (check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db); + my_error(ER_WRONG_DB_NAME, MYF(0), db); goto error; } if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) goto error; /* purecov: inspected */ if (!thd->col_access && check_grant_db(thd,db)) { - net_printf(thd, ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - db); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + db); goto error; } /* grant is checked in mysqld_show_tables */ @@ -3071,7 +3046,7 @@ unsent_create_error: case SQLCOM_SHOW_FIELDS: DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else { @@ -3092,7 +3067,7 @@ unsent_create_error: case SQLCOM_SHOW_KEYS: DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ goto error; #else { @@ -3128,7 +3103,7 @@ unsent_create_error: if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) || ! opt_local_infile) { - send_error(thd,ER_NOT_ALLOWED_COMMAND); + my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); goto error; } if (check_one_table_access(thd, privilege, all_tables)) @@ -3143,15 +3118,13 @@ unsent_create_error: { List *lex_var_list= &lex->var_list; if (all_tables && - ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || - (res= open_and_lock_tables(thd, all_tables)))) - break; + (check_table_access(thd, SELECT_ACL, all_tables, 0) || + open_and_lock_tables(thd, all_tables))) + goto error; if (lex->one_shot_set && not_all_support_one_shot(lex_var_list)) { - my_printf_error(0, "The SET ONE_SHOT syntax is reserved for \ -purposes internal to the MySQL server", MYF(0)); - res= -1; - break; + my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT"); + goto error; } if (!(res= sql_set_variables(thd, lex_var_list))) { @@ -3162,8 +3135,6 @@ purposes internal to the MySQL server", MYF(0)); thd->one_shot_set|= lex->one_shot_set; send_ok(thd); } - if (thd->net.report_error) - res= -1; break; } @@ -3206,7 +3177,7 @@ purposes internal to the MySQL server", MYF(0)); char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3236,7 +3207,7 @@ purposes internal to the MySQL server", MYF(0)); char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - net_printf(thd, ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3259,7 +3230,7 @@ purposes internal to the MySQL server", MYF(0)); break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); goto error; } res=mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : lex->name), @@ -3270,7 +3241,7 @@ purposes internal to the MySQL server", MYF(0)); { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd, ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3293,7 +3264,7 @@ purposes internal to the MySQL server", MYF(0)); break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); goto error; } res=mysql_alter_db(thd,lex->name,&lex->create_info); @@ -3303,14 +3274,14 @@ purposes internal to the MySQL server", MYF(0)); { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - net_printf(thd,ER_WRONG_DB_NAME, lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } if (check_access(thd,SELECT_ACL,lex->name,0,1,0)) break; if (thd->locked_tables || thd->active_transaction()) { - send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); goto error; } res=mysqld_show_create_db(thd,lex->name,&lex->create_info); @@ -3324,13 +3295,13 @@ purposes internal to the MySQL server", MYF(0)); #ifdef HAVE_DLOPEN if ((sph= sp_find_function(thd, lex->spname))) { - net_printf(thd, ER_UDF_EXISTS, lex->spname->m_name.str); + my_error(ER_UDF_EXISTS, MYF(0), lex->spname->m_name.str); goto error; } if (!(res = mysql_create_function(thd,&lex->udf))) send_ok(thd); #else - res= -1; + res= TRUE; #endif break; } @@ -3432,8 +3403,8 @@ purposes internal to the MySQL server", MYF(0)); { if (lex->columns.elements) { - send_error(thd,ER_ILLEGAL_GRANT_FOR_TABLE); - res=1; + my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); + goto error; } else res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant, @@ -3473,9 +3444,7 @@ purposes internal to the MySQL server", MYF(0)); binlog or not. */ bool write_to_binlog; - if (reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog)) - send_error(thd, 0); - else + if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog)) { /* We WANT to write and we CAN write. @@ -3498,7 +3467,6 @@ purposes internal to the MySQL server", MYF(0)); break; #ifndef NO_EMBEDDED_ACCESS_CHECKS case SQLCOM_SHOW_GRANTS: - res=0; if ((thd->priv_user && !strcmp(thd->priv_user,lex->grant_user->user.str)) || !check_access(thd, SELECT_ACL, "mysql",0,1,0)) @@ -3542,9 +3510,7 @@ purposes internal to the MySQL server", MYF(0)); close_thread_tables(thd); // Free tables } if (end_active_trans(thd)) - { - res= -1; - } + goto error; else { thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) | @@ -3567,7 +3533,7 @@ purposes internal to the MySQL server", MYF(0)); send_ok(thd); } else - res= -1; + goto error; break; } case SQLCOM_ROLLBACK: @@ -3589,7 +3555,7 @@ purposes internal to the MySQL server", MYF(0)); send_ok(thd); } else - res= -1; + res= TRUE; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; case SQLCOM_ROLLBACK_TO_SAVEPOINT: @@ -3601,29 +3567,26 @@ purposes internal to the MySQL server", MYF(0)); send_ok(thd); } else - res= -1; + goto error; break; case SQLCOM_SAVEPOINT: if (!ha_savepoint(thd, lex->savepoint_name)) send_ok(thd); else - res= -1; + goto error; break; case SQLCOM_CREATE_PROCEDURE: case SQLCOM_CREATE_SPFUNCTION: { uint namelen; char *name; + int result; - if (!lex->sphead) - { - res= -1; // Shouldn't happen - break; - } + DBUG_ASSERT(lex->sphead); if (! lex->sphead->m_db.str) { - send_error(thd,ER_NO_DB_ERROR); + my_error(ER_NO_DB_ERROR, MYF(0)); delete lex->sphead; lex->sphead= 0; goto error; @@ -3637,7 +3600,7 @@ purposes internal to the MySQL server", MYF(0)); if (udf) { - net_printf(thd, ER_UDF_EXISTS, name); + my_error(ER_UDF_EXISTS, MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; @@ -3647,14 +3610,14 @@ purposes internal to the MySQL server", MYF(0)); if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && !lex->sphead->m_has_return) { - net_printf(thd, ER_SP_NORETURN, name); + my_error(ER_SP_NORETURN, MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; } - res= lex->sphead->create(thd); - switch (res) { + res= (result= lex->sphead->create(thd)); + switch (result) { case SP_OK: send_ok(thd); lex->unit.cleanup(); @@ -3662,19 +3625,19 @@ purposes internal to the MySQL server", MYF(0)); lex->sphead= 0; break; case SP_WRITE_ROW_FAILED: - net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name); + my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; case SP_NO_DB_ERROR: - net_printf(thd, ER_BAD_DB_ERROR, lex->sphead->m_db.str); + my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; default: - net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name); + my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; @@ -3688,8 +3651,8 @@ purposes internal to the MySQL server", MYF(0)); if (!(sp= sp_find_procedure(thd, lex->spname))) { - net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", - lex->spname->m_qname.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE", + lex->spname->m_qname.str); goto error; } else @@ -3703,11 +3666,9 @@ purposes internal to the MySQL server", MYF(0)); /* In case the arguments are subselects... */ if (all_tables && - ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || - (res= open_and_lock_tables(thd, all_tables)))) - { - break; - } + (check_table_access(thd, SELECT_ACL, all_tables, 0) || + open_and_lock_tables(thd, all_tables))) + goto error; #ifndef EMBEDDED_LIBRARY /* @@ -3721,7 +3682,7 @@ purposes internal to the MySQL server", MYF(0)); { if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS)) { - send_error(thd, ER_SP_BADSELECT); + my_error(ER_SP_BADSELECT, MYF(0)); #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif @@ -3754,7 +3715,7 @@ purposes internal to the MySQL server", MYF(0)); thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; } - if (res == 0) + if (!res) send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 : thd->row_count_func)); else goto error; // Substatement should already have sent error @@ -3764,32 +3725,33 @@ purposes internal to the MySQL server", MYF(0)); case SQLCOM_ALTER_PROCEDURE: case SQLCOM_ALTER_FUNCTION: { - res= -1; + int result; uint newname_len= 0; if (lex->name) newname_len= strlen(lex->name); if (newname_len > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, lex->name); - goto error; + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->name); + goto error; } if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) - res= sp_update_procedure(thd, lex->spname, - lex->name, newname_len, &lex->sp_chistics); + result= sp_update_procedure(thd, lex->spname, + lex->name, newname_len, &lex->sp_chistics); else - res= sp_update_function(thd, lex->spname, - lex->name, newname_len, &lex->sp_chistics); - switch (res) + result= sp_update_function(thd, lex->spname, + lex->name, newname_len, &lex->sp_chistics); + res= result; + switch (result) { case SP_OK: send_ok(thd); break; case SP_KEY_NOT_FOUND: - net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; default: - net_printf(thd, ER_SP_CANT_ALTER, SP_COM_STRING(lex), + my_error(ER_SP_CANT_ALTER, MYF(0), SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; } @@ -3798,13 +3760,14 @@ purposes internal to the MySQL server", MYF(0)); case SQLCOM_DROP_PROCEDURE: case SQLCOM_DROP_FUNCTION: { + int result; if (lex->sql_command == SQLCOM_DROP_PROCEDURE) - res= sp_drop_procedure(thd, lex->spname); + result= sp_drop_procedure(thd, lex->spname); else { - res= sp_drop_function(thd, lex->spname); + result= sp_drop_function(thd, lex->spname); #ifdef HAVE_DLOPEN - if (res == SP_KEY_NOT_FOUND) + if (result == SP_KEY_NOT_FOUND) { udf_func *udf = find_udf(lex->spname->m_name.str, lex->spname->m_name.length); @@ -3812,7 +3775,7 @@ purposes internal to the MySQL server", MYF(0)); { if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0)) goto error; - if (!(res = mysql_drop_function(thd,&lex->spname->m_name))) + if (!(result = mysql_drop_function(thd,&lex->spname->m_name))) { send_ok(thd); break; @@ -3821,7 +3784,8 @@ purposes internal to the MySQL server", MYF(0)); } #endif } - switch (res) + res= result; + switch (result) { case SP_OK: send_ok(thd); @@ -3832,34 +3796,31 @@ purposes internal to the MySQL server", MYF(0)); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), SP_COM_STRING(lex), lex->spname->m_name.str); - res= 0; + res= FALSE; send_ok(thd); break; } - net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex), + lex->spname->m_qname.str); goto error; default: - net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_error(ER_SP_DROP_FAILED, MYF(0), SP_COM_STRING(lex), + lex->spname->m_qname.str); goto error; } break; } case SQLCOM_SHOW_CREATE_PROC: { - res= -1; if (lex->spname->m_name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); goto error; } - res= sp_show_create_procedure(thd, lex->spname); - if (res != SP_OK) + if (sp_show_create_procedure(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - net_printf(thd, ER_SP_DOES_NOT_EXIST, - SP_COM_STRING(lex), lex->spname->m_name.str); - res= 0; + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } break; @@ -3868,18 +3829,15 @@ purposes internal to the MySQL server", MYF(0)); { if (lex->spname->m_name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); goto error; } - res= sp_show_create_function(thd, lex->spname); - if (res != SP_OK) + if (sp_show_create_function(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - net_printf(thd, ER_SP_DOES_NOT_EXIST, - SP_COM_STRING(lex), lex->spname->m_name.str); - res= 0; + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } - res= 0; break; } case SQLCOM_SHOW_STATUS_PROC: @@ -3901,13 +3859,9 @@ purposes internal to the MySQL server", MYF(0)); } case SQLCOM_DROP_VIEW: { - if (check_table_access(thd, DROP_ACL, all_tables, 0)) - goto error; - if (end_active_trans(thd)) - { - res= -1; - break; - } + if (check_table_access(thd, DROP_ACL, all_tables, 0) || + end_active_trans(thd)) + goto error; res= mysql_drop_view(thd, first_table, thd->lex->drop_mode); break; } @@ -3975,17 +3929,11 @@ purposes internal to the MySQL server", MYF(0)); thd->row_count_func= -1; } - /* - We end up here if res == 0 and send_ok() has been done, - or res != 0 and no send_error() has yet been done. - */ - if (res < 0) - send_error(thd,thd->killed_errno()); - DBUG_RETURN(res); + DBUG_RETURN(res || thd->net.report_error); error: /* We end up here if send_error() has already been done. */ - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } @@ -4064,7 +4012,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { DBUG_PRINT("error",("No database")); if (!no_errors) - send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ + my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -4091,10 +4039,10 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) - net_printf(thd,ER_ACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ + my_error(ER_ACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -4120,10 +4068,10 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_PRINT("error",("Access denied")); if (!no_errors) - net_printf(thd,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4157,8 +4105,7 @@ bool check_global_access(THD *thd, ulong want_access) if ((thd->master_access & want_access)) return 0; get_privilege_desc(command, sizeof(command), want_access); - net_printf(thd,ER_SPECIFIC_ACCESS_DENIED_ERROR, - command); + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); return 1; #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4270,7 +4217,7 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) { if (!(tables->db=thd->db)) { - send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ + my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: tested */ return TRUE; /* purecov: tested */ } } @@ -4449,7 +4396,7 @@ mysql_new_select(LEX *lex, bool move_down) { if (lex->current_select->order_list.first && !lex->current_select->braces) { - net_printf(lex->thd, ER_WRONG_USAGE, "UNION", "ORDER BY"); + my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY"); return 1; } select_lex->include_neighbour(lex->current_select); @@ -4549,7 +4496,6 @@ void mysql_parse(THD *thd, char *inBuf, uint length) { if (thd->net.report_error) { - send_error(thd, 0, NullS); if (thd->lex->sphead) { if (lex != thd->lex) @@ -4638,7 +4584,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (strlen(field_name) > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, field_name); /* purecov: inspected */ + my_error(ER_TOO_LONG_IDENT, MYF(0), field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (type_modifier & PRI_KEY_FLAG) @@ -4669,7 +4615,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC && type == FIELD_TYPE_TIMESTAMP)) { - net_printf(thd, ER_INVALID_DEFAULT, field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } else if (default_value->type() == Item::NULL_ITEM) @@ -4678,20 +4624,20 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { - net_printf(thd,ER_INVALID_DEFAULT,field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } else if (type_modifier & AUTO_INCREMENT_FLAG) { - net_printf(thd, ER_INVALID_DEFAULT, field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } if (on_update_value && type != FIELD_TYPE_TIMESTAMP) { - net_printf(thd, ER_INVALID_ON_UPDATE, field_name); + my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name); DBUG_RETURN(1); } @@ -4817,7 +4763,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res=default_value->val_str(&str); if (res->length()) { - net_printf(thd,ER_BLOB_CANT_HAVE_DEFAULT,field_name); /* purecov: inspected */ + my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), + field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->def=0; @@ -4837,7 +4784,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, uint tmp_length=new_field->length; if (tmp_length > PRECISION_FOR_DOUBLE) { - net_printf(thd,ER_WRONG_FIELD_SPEC,field_name); + my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); DBUG_RETURN(1); } else if (tmp_length > PRECISION_FOR_FLOAT) @@ -4923,7 +4870,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { if (interval->count > sizeof(longlong)*8) { - net_printf(thd,ER_TOO_BIG_SET,field_name); /* purecov: inspected */ + my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->pack_length=(interval->count+7)/8; @@ -4953,7 +4900,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, ¬_used2, ¬_used3); if (thd->cuted_fields) { - net_printf(thd,ER_INVALID_DEFAULT,field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } @@ -4979,7 +4926,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res->strip_sp(); if (!find_type(interval, res->ptr(), res->length(), 0)) { - net_printf(thd,ER_INVALID_DEFAULT,field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } @@ -4993,14 +4940,14 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING && type != FIELD_TYPE_GEOMETRY)) { - net_printf(thd,ER_TOO_BIG_FIELDLENGTH,field_name, - MAX_FIELD_CHARLENGTH); /* purecov: inspected */ + my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name, + MAX_FIELD_CHARLENGTH); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } type_modifier&= AUTO_INCREMENT_FLAG; if ((~allowed_type_modifier) & type_modifier) { - net_printf(thd,ER_WRONG_FIELD_SPEC,field_name); + my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); DBUG_RETURN(1); } if (!new_field->pack_length) @@ -5130,7 +5077,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (check_table_name(table->table.str,table->table.length) || table->db.str && check_db_name(table->db.str)) { - net_printf(thd, ER_WRONG_TABLE_NAME, table->table.str); + my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); DBUG_RETURN(0); } @@ -5138,7 +5085,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, { if (table->sel) { - net_printf(thd,ER_DERIVED_MUST_HAVE_ALIAS); + my_error(ER_DERIVED_MUST_HAVE_ALIAS, MYF(0)); DBUG_RETURN(0); } if (!(alias_str=thd->memdup(alias_str,table->table.length+1))) @@ -5192,7 +5139,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) && !strcmp(ptr->db, tables->db)) { - net_printf(thd,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ + my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */ } } @@ -5688,7 +5635,7 @@ void kill_one_thread(THD *thd, ulong id, bool only_kill_query) if (!error) send_ok(thd); else - net_printf(thd,error,id); + my_error(error, MYF(0), id); } /* Clear most status variables */ @@ -5769,7 +5716,7 @@ bool check_simple_select() char command[80]; strmake(command, thd->lex->yylval->symbol.str, min(thd->lex->yylval->symbol.length, sizeof(command)-1)); - net_printf(thd, ER_CANT_USE_OPTION_HERE, command); + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command); return 1; } return 0; @@ -5857,7 +5804,7 @@ Item * all_any_subquery_creator(Item *left_expr, One should normally create all indexes with CREATE TABLE or ALTER TABLE. */ -int mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) +bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) { List fields; ALTER_INFO alter_info; @@ -5875,7 +5822,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) } -int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) +bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) { List fields; List keys; @@ -5903,12 +5850,11 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) tables Global/local table list (have to be the same) RETURN VALUE - 0 OK - 1 Error (message is sent to user) - -1 Error (message is not sent to user) + FALSE OK + TRUE Error */ -int multi_update_precheck(THD *thd, TABLE_LIST *tables) +bool multi_update_precheck(THD *thd, TABLE_LIST *tables) { const char *msg= 0; TABLE_LIST *table; @@ -5919,7 +5865,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (select_lex->item_list.elements != lex->value_list.elements) { my_error(ER_WRONG_VALUE_COUNT, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* Ensure that we have UPDATE or SELECT privilege for each table @@ -5933,7 +5879,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0) || grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); table->table_in_first_from_clause= 1; } @@ -5949,7 +5895,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0) || grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } } @@ -5962,9 +5908,9 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (msg) { my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /* @@ -5977,11 +5923,11 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) table_count Pointer to table counter RETURN VALUE - 0 OK - 1 error (message is sent to user) - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) + +bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) { SELECT_LEX *select_lex= &thd->lex->select_lex; TABLE_LIST *aux_tables= @@ -5996,11 +5942,11 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) || check_table_access(thd,SELECT_ACL, tables,0) || check_table_access(thd,DELETE_ACL, aux_tables,0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) { my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local) { @@ -6018,12 +5964,12 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) { my_error(ER_UNKNOWN_TABLE, MYF(0), target_tbl->real_name, "MULTI DELETE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } walk->lock_type= target_tbl->lock_type; target_tbl->correspondent_table= walk; // Remember corresponding table } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -6036,12 +5982,11 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) tables Global table list RETURN VALUE - 0 OK - 1 Error (message is sent to user) - -1 Error (message is not sent to user) + FALSE OK + TRUE Error */ -int insert_select_precheck(THD *thd, TABLE_LIST *tables) +bool insert_select_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("insert_select_precheck"); /* @@ -6050,7 +5995,7 @@ int insert_select_precheck(THD *thd, TABLE_LIST *tables) */ ulong privilege= (thd->lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL); - DBUG_RETURN(check_one_table_access(thd, privilege, tables) ? 1 : 0); + DBUG_RETURN(check_one_table_access(thd, privilege, tables)); } @@ -6063,21 +6008,20 @@ int insert_select_precheck(THD *thd, TABLE_LIST *tables) tables Global table list RETURN VALUE - 0 OK - 1 Error (message is sent to user) - -1 Error (message is not sent to user) + FALSE OK + TRUE Error */ -int update_precheck(THD *thd, TABLE_LIST *tables) +bool update_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("update_precheck"); if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements) { my_error(ER_WRONG_VALUE_COUNT, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } - DBUG_RETURN((check_db_used(thd, tables) || - check_one_table_access(thd, UPDATE_ACL, tables)) ? 1 : 0); + DBUG_RETURN(check_db_used(thd, tables) || + check_one_table_access(thd, UPDATE_ACL, tables)); } @@ -6090,19 +6034,18 @@ int update_precheck(THD *thd, TABLE_LIST *tables) tables Global table list RETURN VALUE - 0 OK - 1 error (message is sent to user) - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int delete_precheck(THD *thd, TABLE_LIST *tables) +bool delete_precheck(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("delete_precheck"); if (check_one_table_access(thd, DELETE_ACL, tables)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); /* Set privilege for the WHERE clause */ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -6115,12 +6058,11 @@ int delete_precheck(THD *thd, TABLE_LIST *tables) tables Global table list RETURN VALUE - 0 OK - 1 error (message is sent to user) - -1 error (message is not sent to user) + FALSE OK + TRUE error */ -int insert_precheck(THD *thd, TABLE_LIST *tables, bool update) +bool insert_precheck(THD *thd, TABLE_LIST *tables, bool update) { LEX *lex= thd->lex; DBUG_ENTER("insert_precheck"); @@ -6129,14 +6071,14 @@ int insert_precheck(THD *thd, TABLE_LIST *tables, bool update) INSERT_ACL | DELETE_ACL : INSERT_ACL | update); if (check_one_table_access(thd, privilege, tables)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if (lex->select_lex.item_list.elements != lex->value_list.elements) { my_error(ER_WRONG_VALUE_COUNT, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -6150,13 +6092,12 @@ int insert_precheck(THD *thd, TABLE_LIST *tables, bool update) create_table Table which will be created RETURN VALUE - 0 OK - 1 Error (message is sent to user) - -1 Error (message is not sent to user) + FALSE OK + TRUE Error */ -int create_table_precheck(THD *thd, TABLE_LIST *tables, - TABLE_LIST *create_table) +bool create_table_precheck(THD *thd, TABLE_LIST *tables, + TABLE_LIST *create_table) { LEX *lex= thd->lex; DBUG_ENTER("create_table_precheck"); @@ -6168,10 +6109,9 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables, check_merge_table_access(thd, create_table->db, (TABLE_LIST *) lex->create_info.merge_list.first)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); DBUG_RETURN((grant_option && want_priv != CREATE_TMP_ACL && - check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0)) ? - 1 : 0); + check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0))); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 982e00391ef..aa5da98f56f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -122,16 +122,13 @@ inline bool is_param_null(const uchar *pos, ulong param_no) enum { STMT_QUERY_LOG_LENGTH= 8192 }; -enum enum_send_error { DONT_SEND_ERROR= 0, SEND_ERROR }; - /* Seek prepared statement in statement map by id: returns zero if statement was not found, pointer otherwise. */ static Prepared_statement * -find_prepared_statement(THD *thd, ulong id, const char *where, - enum enum_send_error se) +find_prepared_statement(THD *thd, ulong id, const char *where) { Statement *stmt= thd->stmt_map.find(id); @@ -139,8 +136,6 @@ find_prepared_statement(THD *thd, ulong id, const char *where, { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), 22, llstr(id, llbuf), where); - if (se == SEND_ERROR) - send_error(thd); return 0; } return (Prepared_statement *) stmt; @@ -180,7 +175,7 @@ static bool send_prep_stmt(Prepared_statement *stmt, thd->client_stmt_id= stmt->id; thd->client_param_count= stmt->param_count; - thd->net.last_errno= 0; + thd->clear_error(); return 0; } @@ -881,24 +876,23 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt, tables global/local table list RETURN VALUE - 0 ok - 1 error, sent to the client - -1 error, not sent to client + FALSE OK + TRUE error */ -static int mysql_test_insert(Prepared_statement *stmt, - TABLE_LIST *table_list, - List &fields, - List &values_list, - List &update_fields, - List &update_values, - enum_duplicates duplic) +static bool mysql_test_insert(Prepared_statement *stmt, + TABLE_LIST *table_list, + List &fields, + List &values_list, + List &update_fields, + List &update_values, + enum_duplicates duplic) { THD *thd= stmt->thd; LEX *lex= stmt->lex; List_iterator_fast its(values_list); List_item *values; - int res; + bool res; my_bool update= (lex->value_list.elements ? UPDATE_ACL : 0); DBUG_ENTER("mysql_test_insert"); @@ -909,9 +903,9 @@ static int mysql_test_insert(Prepared_statement *stmt, open temporary memory pool for temporary data allocated by derived tables & preparation procedure */ - if ((res= open_and_lock_tables(thd, table_list))) + if (open_and_lock_tables(thd, table_list)) { - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } if ((values= its++)) @@ -958,14 +952,13 @@ error: tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int mysql_test_update(Prepared_statement *stmt, - TABLE_LIST *table_list) +static bool mysql_test_update(Prepared_statement *stmt, + TABLE_LIST *table_list) { - int res; + bool res; THD *thd= stmt->thd; SELECT_LEX *select= &stmt->lex->select_lex; DBUG_ENTER("mysql_test_update"); @@ -1010,28 +1003,27 @@ static int mysql_test_update(Prepared_statement *stmt, tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ static int mysql_test_delete(Prepared_statement *stmt, TABLE_LIST *table_list) { - int res; THD *thd= stmt->thd; LEX *lex= stmt->lex; DBUG_ENTER("mysql_test_delete"); - if ((res= delete_precheck(thd, table_list))) - DBUG_RETURN(res); + if (delete_precheck(thd, table_list)) + DBUG_RETURN(TRUE); - if (!(res=open_and_lock_tables(thd, table_list))) + if (!open_and_lock_tables(thd, table_list)) { - res= mysql_prepare_delete(thd, table_list, &lex->select_lex.where); + mysql_prepare_delete(thd, table_list, &lex->select_lex.where); lex->unit.cleanup(); + DBUG_RETURN(FALSE) } /* TODO: here we should send types of placeholders to the client. */ - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } @@ -1046,9 +1038,8 @@ static int mysql_test_delete(Prepared_statement *stmt, tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error, sent to client */ static int mysql_test_select(Prepared_statement *stmt, @@ -1057,7 +1048,7 @@ static int mysql_test_select(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX_UNIT *unit= &lex->unit; - int result; + bool result; DBUG_ENTER("mysql_test_select"); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -1065,26 +1056,21 @@ static int mysql_test_select(Prepared_statement *stmt, if (tables) { if (check_table_access(thd, privilege, tables,0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } else if (check_access(thd, privilege, any_db,0,0,0)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); #endif if ((result= open_and_lock_tables(thd, tables))) - { - result= 1; // Error sent - send_error(thd); goto err; - } - result= 1; + result= TRUE; thd->used_tables= 0; // Updated by setup_fields // JOIN::prepare calls if (unit->prepare(thd, 0, 0)) { - send_error(thd); goto err_prep; } if (!text_protocol) @@ -1106,7 +1092,7 @@ static int mysql_test_select(Prepared_statement *stmt, goto err_prep; } } - result= 0; // ok + result= FALSE; // ok err_prep: unit->cleanup(); @@ -1125,30 +1111,27 @@ err: values list of expressions RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error, sent to client */ -static int mysql_test_do_fields(Prepared_statement *stmt, +static bool mysql_test_do_fields(Prepared_statement *stmt, TABLE_LIST *tables, List *values) { DBUG_ENTER("mysql_test_do_fields"); THD *thd= stmt->thd; - int res= 0; - if (tables && (res= check_table_access(thd, SELECT_ACL, tables, 0))) - DBUG_RETURN(res); + bool res; + if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) + DBUG_RETURN(TRUE); - if (tables && (res= open_and_lock_tables(thd, tables))) + if (tables && open_and_lock_tables(thd, tables)) { - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } res= setup_fields(thd, 0, 0, *values, 0, 0, 0); stmt->lex->unit.cleanup(); - if (res) - DBUG_RETURN(-1); - DBUG_RETURN(0); + DBUG_RETURN(res); } @@ -1162,22 +1145,21 @@ static int mysql_test_do_fields(Prepared_statement *stmt, values list of expressions RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int mysql_test_set_fields(Prepared_statement *stmt, - TABLE_LIST *tables, - List *var_list) +static bool mysql_test_set_fields(Prepared_statement *stmt, + TABLE_LIST *tables, + List *var_list) { DBUG_ENTER("mysql_test_set_fields"); List_iterator_fast it(*var_list); THD *thd= stmt->thd; set_var_base *var; - int res= 0; + bool res= 0; - if (tables && (res= check_table_access(thd, SELECT_ACL, tables, 0))) - DBUG_RETURN(res); + if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) + DBUG_RETURN(TRUE); if (tables && (res= open_and_lock_tables(thd, tables))) goto error; @@ -1186,7 +1168,7 @@ static int mysql_test_set_fields(Prepared_statement *stmt, if (var->light_check(thd)) { stmt->lex->unit.cleanup(); - res= -1; + res= TRUE; goto error; } } @@ -1206,18 +1188,17 @@ error: specific_prepare - function of command specific prepare RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int select_like_statement_test(Prepared_statement *stmt, - TABLE_LIST *tables, - int (*specific_prepare)(THD *thd)) +static bool select_like_statement_test(Prepared_statement *stmt, + TABLE_LIST *tables, + bool (*specific_prepare)(THD *thd)) { DBUG_ENTER("select_like_statement_test"); THD *thd= stmt->thd; LEX *lex= stmt->lex; - int res= 0; + bool res= 0; if (tables && (res= open_and_lock_tables(thd, tables))) goto end; @@ -1230,7 +1211,7 @@ static int select_like_statement_test(Prepared_statement *stmt, // JOIN::prepare calls if (lex->unit.prepare(thd, 0, 0)) { - res= thd->net.report_error ? -1 : 1; + res= TRUE; } end: lex->unit.cleanup(); @@ -1287,16 +1268,15 @@ static int mysql_test_create_table(Prepared_statement *stmt) tables list of tables queries RETURN VALUE - 0 success - 1 error, sent to client - -1 error, not sent to client + FALSE success + TRUE error */ -static int mysql_test_multiupdate(Prepared_statement *stmt, + +static bool mysql_test_multiupdate(Prepared_statement *stmt, TABLE_LIST *tables) { - int res; - if ((res= multi_update_precheck(stmt->thd, tables))) - return res; + if (multi_update_precheck(stmt->thd, tables)) + return TRUE; return select_like_statement_test(stmt, tables, &mysql_multi_update_prepare); } @@ -1477,8 +1457,6 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) if (res == 0) DBUG_RETURN(text_protocol? 0 : send_prep_stmt(stmt, 0)); error: - if (res < 0) - send_error(thd,thd->killed_errno()); DBUG_RETURN(1); } @@ -1500,10 +1478,7 @@ static bool init_param_array(Prepared_statement *stmt) alloc_root(&stmt->thd->mem_root, sizeof(Item_param*) * stmt->param_count); if (!stmt->param_array) - { - send_error(stmt->thd, ER_OUT_OF_RESOURCES); return 1; - } for (to= stmt->param_array; to < stmt->param_array + stmt->param_count; ++to) @@ -1527,10 +1502,10 @@ static bool init_param_array(Prepared_statement *stmt) name NULL or statement name. For unnamed statements binary PS protocol is used, for named statements text protocol is used. - RETURN - 0 OK, statement prepared successfully - other Error - + RETURN + FALSE OK, statement prepared successfully + TRUE Error + NOTES This function parses the query and sends the total number of parameters and resultset metadata information back to client (if any), without @@ -1544,21 +1519,18 @@ static bool init_param_array(Prepared_statement *stmt) */ -int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, - LEX_STRING *name) +bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, + LEX_STRING *name) { LEX *lex; Prepared_statement *stmt= new Prepared_statement(thd); - int error; + bool error; DBUG_ENTER("mysql_stmt_prepare"); DBUG_PRINT("prep_query", ("%s", packet)); if (stmt == 0) - { - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); - } + DBUG_RETURN(TRUE); if (name) { @@ -1567,16 +1539,14 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, name->length))) { delete stmt; - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } if (thd->stmt_map.insert(stmt)) { delete stmt; - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } thd->set_n_backup_statement(stmt, &thd->stmt_backup); @@ -1588,8 +1558,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, thd->restore_backup_item_arena(stmt, &thd->stmt_backup); /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } mysql_log.write(thd, COM_PREPARE, "%s", packet); @@ -1768,8 +1737,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) packet+= 9; /* stmt_id + 5 bytes of flags */ - if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute", - SEND_ERROR))) + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute"))) DBUG_VOID_RETURN; DBUG_PRINT("exec_query:", ("%s", stmt->query)); @@ -1777,7 +1745,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) /* Check if we got an error when sending long data */ if (stmt->state == Item_arena::ERROR) { - send_error(thd, stmt->last_errno, stmt->last_error); + my_message(stmt->last_errno, stmt->last_error, MYF(0)); DBUG_VOID_RETURN; } @@ -1795,10 +1763,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) { if (!stmt->cursor && !(stmt->cursor= new (&stmt->mem_root) Cursor())) - { - send_error(thd, ER_OUT_OF_RESOURCES); DBUG_VOID_RETURN; - } /* If lex->result is set, mysql_execute_command will use it */ stmt->lex->result= &stmt->cursor->result; } @@ -1866,7 +1831,6 @@ set_params_data_err: reset_stmt_params(stmt); my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute"); err: - send_error(thd); DBUG_VOID_RETURN; } @@ -1892,14 +1856,12 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) { my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_name->length, stmt_name->str, "EXECUTE"); - send_error(thd); DBUG_VOID_RETURN; } if (stmt->param_count != thd->lex->prepared_stmt_params.elements) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE"); - send_error(thd); DBUG_VOID_RETURN; } @@ -1910,7 +1872,6 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) &expanded_query)) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE"); - send_error(thd); } execute_stmt(thd, stmt, &expanded_query); DBUG_VOID_RETURN; @@ -1994,7 +1955,6 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) !stmt->cursor->is_open()) { my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_id, "fetch"); - send_error(thd); DBUG_VOID_RETURN; } @@ -2018,9 +1978,6 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) thd->set_statement(&thd->stmt_backup); thd->set_item_arena(&thd->stmt_backup); - if (error && error != -4) - send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_VOID_RETURN; } @@ -2050,8 +2007,7 @@ void mysql_stmt_reset(THD *thd, char *packet) DBUG_ENTER("mysql_stmt_reset"); - if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset", - SEND_ERROR))) + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset"))) DBUG_VOID_RETURN; stmt->state= Item_arena::PREPARED; @@ -2081,8 +2037,7 @@ void mysql_stmt_free(THD *thd, char *packet) DBUG_ENTER("mysql_stmt_free"); - if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close", - DONT_SEND_ERROR))) + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close"))) DBUG_VOID_RETURN; /* Statement map deletes statement on erase */ @@ -2132,8 +2087,8 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) stmt_id= uint4korr(packet); packet+= 4; - if (!(stmt=find_prepared_statement(thd, stmt_id, "mysql_stmt_send_long_data", - DONT_SEND_ERROR))) + if (!(stmt=find_prepared_statement(thd, stmt_id, + "mysql_stmt_send_long_data"))) DBUG_VOID_RETURN; param_number= uint2korr(packet); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 9e38a65d412..fe7e8432ec6 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -278,41 +278,39 @@ bool log_in_use(const char* log_name) return result; } -int purge_error_message(THD* thd, int res) +bool purge_error_message(THD* thd, int res) { - const char *errmsg= 0; + uint errmsg= 0; switch (res) { case 0: break; - case LOG_INFO_EOF: errmsg= "Target log not found in binlog index"; break; - case LOG_INFO_IO: errmsg= "I/O error reading log index file"; break; - case LOG_INFO_INVALID: - errmsg= "Server configuration does not permit binlog purge"; break; - case LOG_INFO_SEEK: errmsg= "Failed on fseek()"; break; - case LOG_INFO_MEM: errmsg= "Out of memory"; break; - case LOG_INFO_FATAL: errmsg= "Fatal error during purge"; break; - case LOG_INFO_IN_USE: errmsg= "A purgeable log is in use, will not purge"; - break; - default: errmsg= "Unknown error during purge"; break; + case LOG_INFO_EOF: errmsg= ER_UNKNOWN_TARGET_BINLOG; break; + case LOG_INFO_IO: errmsg= ER_IO_ERR_LOG_INDEX_READ; break; + case LOG_INFO_INVALID:errmsg= ER_BINLOG_PURGE_PROHIBITED; break; + case LOG_INFO_SEEK: errmsg= ER_FSEEK_FAIL; break; + case LOG_INFO_MEM: errmsg= ER_OUT_OF_RESOURCES; break; + case LOG_INFO_FATAL: errmsg= ER_BINLOG_PURGE_FATAL_ERR; break; + case LOG_INFO_IN_USE: errmsg= ER_LOG_IN_USE; break; + default: errmsg= ER_LOG_PURGE_UNKNOWN_ERR; break; } if (errmsg) { - send_error(thd, 0, errmsg); - return 1; + my_error(errmsg, MYF(0)); + return TRUE; } send_ok(thd); - return 0; + return FALSE; } -int purge_master_logs(THD* thd, const char* to_log) +bool purge_master_logs(THD* thd, const char* to_log) { char search_file_name[FN_REFLEN]; if (!mysql_bin_log.is_open()) { send_ok(current_thd); - return 0; + return FALSE; } mysql_bin_log.make_log_name(search_file_name, to_log); @@ -322,10 +320,10 @@ int purge_master_logs(THD* thd, const char* to_log) } -int purge_master_logs_before_date(THD* thd, time_t purge_time) +bool purge_master_logs_before_date(THD* thd, time_t purge_time) { - int res = mysql_bin_log.purge_logs_before_date(purge_time); - return purge_error_message(thd ,res); + return purge_error_message(thd, + mysql_bin_log.purge_logs_before_date(purge_time)); } int test_for_non_eof_log_read_errors(int error, const char **errmsg) @@ -753,7 +751,7 @@ err: pthread_mutex_unlock(&LOCK_thread_count); if (file >= 0) (void) my_close(file, MYF(MY_WME)); - send_error(thd, my_errno, errmsg); + my_message(my_errno, errmsg, MYF(0)); DBUG_VOID_RETURN; } @@ -1054,7 +1052,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id) } -int change_master(THD* thd, MASTER_INFO* mi) +bool change_master(THD* thd, MASTER_INFO* mi) { int thread_mask; const char* errmsg= 0; @@ -1065,9 +1063,9 @@ int change_master(THD* thd, MASTER_INFO* mi) init_thread_mask(&thread_mask,mi,0 /*not inverse*/); if (thread_mask) // We refuse if any slave thread is running { - net_printf(thd,ER_SLAVE_MUST_STOP); + my_error(ER_SLAVE_MUST_STOP, MYF(0)); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } thd->proc_info = "Changing master"; @@ -1075,9 +1073,9 @@ int change_master(THD* thd, MASTER_INFO* mi) // TODO: see if needs re-write if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) { - send_error(thd, ER_MASTER_INFO); + my_error(ER_MASTER_INFO, MYF(0)); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } /* @@ -1194,9 +1192,9 @@ int change_master(THD* thd, MASTER_INFO* mi) 0 /* not only reset, but also reinit */, &errmsg)) { - net_printf(thd, 0, "Failed purging old relay logs: %s",errmsg); + my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } else @@ -1210,9 +1208,9 @@ int change_master(THD* thd, MASTER_INFO* mi) 0 /*no data lock*/, &msg, 0)) { - net_printf(thd,0,"Failed initializing relay log position: %s",msg); + my_error(ER_RELAY_LOG_INIT, MYF(0), msg); unlock_slave_threads(mi); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } mi->rli.group_master_log_pos = mi->master_log_pos; @@ -1254,7 +1252,7 @@ int change_master(THD* thd, MASTER_INFO* mi) unlock_slave_threads(mi); thd->proc_info = 0; send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } int reset_master(THD* thd) @@ -1285,7 +1283,7 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, } -int show_binlog_events(THD* thd) +bool show_binlog_events(THD* thd) { Protocol *protocol= thd->protocol; DBUG_ENTER("show_binlog_events"); @@ -1299,7 +1297,7 @@ int show_binlog_events(THD* thd) Log_event::init_show_field_list(&field_list); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); if (mysql_bin_log.is_open()) { @@ -1405,18 +1403,18 @@ err: { my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), "SHOW BINLOG EVENTS", errmsg); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); pthread_mutex_lock(&LOCK_thread_count); thd->current_linfo = 0; pthread_mutex_unlock(&LOCK_thread_count); - DBUG_RETURN(0); + DBUG_RETURN(TRUE); } -int show_binlog_info(THD* thd) +bool show_binlog_info(THD* thd) { Protocol *protocol= thd->protocol; DBUG_ENTER("show_binlog_info"); @@ -1429,7 +1427,7 @@ int show_binlog_info(THD* thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); if (mysql_bin_log.is_open()) @@ -1442,10 +1440,10 @@ int show_binlog_info(THD* thd) protocol->store(&binlog_do_db); protocol->store(&binlog_ignore_db); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -1457,11 +1455,11 @@ int show_binlog_info(THD* thd) thd Thread specific variable RETURN VALUES - 0 ok - 1 error (Error message sent to client) + FALSE OK + TRUE error */ -int show_binlogs(THD* thd) +bool show_binlogs(THD* thd) { IO_CACHE *index_file; char fname[FN_REFLEN]; @@ -1472,15 +1470,14 @@ int show_binlogs(THD* thd) if (!mysql_bin_log.is_open()) { - //TODO: Replace with ER() error message - send_error(thd, 0, "You are not using binary logging"); + my_error(ER_NO_BINARY_LOGGING, MYF(0)); return 1; } field_list.push_back(new Item_empty_string("Log_name", 255)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); mysql_bin_log.lock_index(); index_file=mysql_bin_log.get_index_file(); @@ -1498,11 +1495,11 @@ int show_binlogs(THD* thd) } mysql_bin_log.unlock_index(); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: mysql_bin_log.unlock_index(); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_repl.h b/sql/sql_repl.h index c39ef90114d..3f457a060cb 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -27,17 +27,17 @@ File open_binlog(IO_CACHE *log, const char *log_file_name, int start_slave(THD* thd, MASTER_INFO* mi, bool net_report); int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report); -int change_master(THD* thd, MASTER_INFO* mi); -int show_binlog_events(THD* thd); +bool change_master(THD* thd, MASTER_INFO* mi); +bool show_binlog_events(THD* thd); int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, const char* log_file_name2, ulonglong log_pos2); int reset_slave(THD *thd, MASTER_INFO* mi); int reset_master(THD* thd); -int purge_master_logs(THD* thd, const char* to_log); -int purge_master_logs_before_date(THD* thd, time_t purge_time); +bool purge_master_logs(THD* thd, const char* to_log); +bool purge_master_logs_before_date(THD* thd, time_t purge_time); bool log_in_use(const char* log_name); void adjust_linfo_offsets(my_off_t purge_offset); -int show_binlogs(THD* thd); +bool show_binlogs(THD* thd); extern int init_master_info(MASTER_INFO* mi); void kill_zombie_dump_threads(uint32 slave_server_id); int check_binlog_magic(IO_CACHE* log, const char** errmsg); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e104ac1ca38..8cbc7589d26 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -194,9 +194,9 @@ static Item *remove_additional_cond(Item* conds); This handles SELECT with and without UNION */ -int handle_select(THD *thd, LEX *lex, select_result *result) +bool handle_select(THD *thd, LEX *lex, select_result *result) { - int res; + bool res; register SELECT_LEX *select_lex = &lex->select_lex; DBUG_ENTER("handle_select"); @@ -223,14 +223,14 @@ int handle_select(THD *thd, LEX *lex, select_result *result) /* Don't set res if it's -1 as we may want this later */ DBUG_PRINT("info",("res: %d report_error: %d", res, thd->net.report_error)); - if (thd->net.report_error) - res= 1; + res|= thd->net.report_error; if (unlikely(res)) { - if (res > 0) - result->send_error(0, NullS); + /* + If we have real error reported erly then this will be ignored + */ + result->send_error(ER_UNKNOWN_ERROR, NullS); result->abort(); - res= 1; // Error sent to client } DBUG_RETURN(res); } @@ -395,21 +395,20 @@ JOIN::prepare(Item ***rref_pointer_array, { if (!test_if_subpart(procedure->group,group_list)) { /* purecov: inspected */ - my_message(0,"Can't handle procedures with differents groups yet", - MYF(0)); /* purecov: inspected */ + my_error(ER_DIFF_GROUPS_PROC, MYF(0)); /* purecov: inspected */ goto err; /* purecov: inspected */ } } #ifdef NOT_NEEDED else if (!group_list && procedure->flags & PROC_GROUP) { - my_message(0,"Select must have a group with this procedure",MYF(0)); + my_message(ER_NO_GROUP_FOR_PROC, MYF(0)); goto err; } #endif if (order && (procedure->flags & PROC_NO_SORT)) { /* purecov: inspected */ - my_message(0,"Can't use order with this procedure",MYF(0)); /* purecov: inspected */ + my_error(ER_ORDER_WITH_PROC, MYF(0)); /* purecov: inspected */ goto err; /* purecov: inspected */ } } @@ -1890,7 +1889,7 @@ Cursor::~Cursor() /*********************************************************************/ -int +bool mysql_select(THD *thd, Item ***rref_pointer_array, TABLE_LIST *tables, uint wild_num, List &fields, COND *conds, uint og_num, ORDER *order, ORDER *group, @@ -1898,7 +1897,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, select_result *result, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) { - int err; + bool err; bool free_join= 1; DBUG_ENTER("mysql_select"); @@ -1906,7 +1905,10 @@ mysql_select(THD *thd, Item ***rref_pointer_array, if (select_lex->join != 0) { join= select_lex->join; - // is it single SELECT in derived table, called in derived table creation + /* + is it single SELECT in derived table, called in derived table + creation + */ if (select_lex->linkage != DERIVED_TABLE_TYPE || (select_options & SELECT_DESCRIBE)) { @@ -1915,7 +1917,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, //here is EXPLAIN of subselect or derived table if (join->change_result(result)) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } else @@ -1934,7 +1936,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, else { if (!(join= new JOIN(thd, fields, select_options, result))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); thd->proc_info="init"; thd->used_tables=0; // Updated by setup_fields if (join->prepare(rref_pointer_array, tables, wild_num, @@ -1982,10 +1984,8 @@ err: { thd->proc_info="end"; err= join->cleanup(); - if (thd->net.report_error) - err= -1; delete join; - DBUG_RETURN(err); + DBUG_RETURN(err || thd->net.report_error); } DBUG_RETURN(join->error); } @@ -11557,10 +11557,10 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } -int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) +bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) { DBUG_ENTER("mysql_explain_union"); - int res= 0; + bool res= 0; SELECT_LEX *first= unit->first_select(); for (SELECT_LEX *sl= first; @@ -11611,9 +11611,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) first->options | thd->options | SELECT_DESCRIBE, result, unit, first); } - if (res > 0 || thd->net.report_error) - res= -1; // mysql_explain_select do not report error - DBUG_RETURN(res); + DBUG_RETURN(res || thd->net.report_error); } @@ -11824,17 +11822,17 @@ void st_select_lex::print(THD *thd, String *str) res new select_result object RETURN - 0 - OK - -1 - error + FALSE - OK + TRUE - error */ -int JOIN::change_result(select_result *res) +bool JOIN::change_result(select_result *res) { DBUG_ENTER("JOIN::change_result"); result= res; if (!procedure && result->prepare(fields_list, select_lex->master_unit())) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } diff --git a/sql/sql_select.h b/sql/sql_select.h index eb80f3ee608..e1f98059618 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -330,7 +330,7 @@ class JOIN :public Sql_alloc return (do_send_rows && tmp_table_param.sum_func_count != 0 && !group_list); } - int change_result(select_result *result); + bool change_result(select_result *result); }; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 14bef9d2236..b9c2a5d8e18 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -48,7 +48,7 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *packet); A database is a directory in the mysql_data_home directory */ -int +bool mysqld_show_dbs(THD *thd,const char *wild) { Item_string *field=new Item_string("",0,thd->charset()); @@ -68,9 +68,9 @@ mysqld_show_dbs(THD *thd,const char *wild) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if (mysql_find_files(thd,&files,NullS,mysql_data_home,wild,1)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); List_iterator_fast it(files); while ((file_name=it++)) @@ -84,11 +84,11 @@ mysqld_show_dbs(THD *thd,const char *wild) protocol->prepare_for_resend(); protocol->store(file_name, system_charset_info); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -96,7 +96,7 @@ mysqld_show_dbs(THD *thd,const char *wild) List all open tables in a database ***************************************************************************/ -int mysqld_show_open_tables(THD *thd,const char *wild) +bool mysqld_show_open_tables(THD *thd,const char *wild) { List field_list; OPEN_TABLE_LIST *open_list; @@ -110,10 +110,10 @@ int mysqld_show_open_tables(THD *thd,const char *wild) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); if (!(open_list=list_open_tables(thd,wild)) && thd->is_fatal_error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); for (; open_list ; open_list=open_list->next) { @@ -124,11 +124,11 @@ int mysqld_show_open_tables(THD *thd,const char *wild) protocol->store_tiny((longlong) open_list->locked); if (protocol->write()) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -137,7 +137,7 @@ int mysqld_show_open_tables(THD *thd,const char *wild) ** A table is a .frm file in the current databasedir ***************************************************************************/ -int mysqld_show_tables(THD *thd, const char *db, const char *wild, +bool mysqld_show_tables(THD *thd, const char *db, const char *wild, bool show_type) { Item_string *field=new Item_string("",0,thd->charset()); @@ -162,10 +162,9 @@ int mysqld_show_tables(THD *thd, const char *db, const char *wild, if (show_type) field_list.push_back(new Item_empty_string("table_type", 10)); if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - if (mysql_find_files(thd,&files,db,path,wild,0)) - DBUG_RETURN(-1); + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF) || + mysql_find_files(thd,&files,db,path,wild,0)) + DBUG_RETURN(TRUE); List_iterator_fast it(files); while ((file_name=it++)) { @@ -190,17 +189,17 @@ int mysqld_show_tables(THD *thd, const char *db, const char *wild, } } if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /*************************************************************************** ** List all table types supported ***************************************************************************/ -int mysqld_show_storage_engines(THD *thd) +bool mysqld_show_storage_engines(THD *thd) { List field_list; Protocol *protocol= thd->protocol; @@ -212,7 +211,7 @@ int mysqld_show_storage_engines(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); const char *default_type_name= ha_get_storage_engine((enum db_type)thd->variables.table_type); @@ -230,10 +229,10 @@ int mysqld_show_storage_engines(THD *thd) protocol->store(option_name, system_charset_info); protocol->store(types->comment, system_charset_info); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -275,7 +274,7 @@ static struct show_privileges_st sys_privileges[]= {NullS, NullS, NullS} }; -int mysqld_show_privileges(THD *thd) +bool mysqld_show_privileges(THD *thd) { List field_list; Protocol *protocol= thd->protocol; @@ -287,7 +286,7 @@ int mysqld_show_privileges(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); show_privileges_st *privilege= sys_privileges; for (privilege= sys_privileges; privilege->privilege ; privilege++) @@ -297,10 +296,10 @@ int mysqld_show_privileges(THD *thd) protocol->store(privilege->context, system_charset_info); protocol->store(privilege->comment, system_charset_info); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -340,7 +339,7 @@ static struct show_column_type_st sys_column_types[]= "A very small integer"}, }; -int mysqld_show_column_types(THD *thd) +bool mysqld_show_column_types(THD *thd) { List field_list; Protocol *protocol= thd->protocol; @@ -363,7 +362,7 @@ int mysqld_show_column_types(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); /* TODO: Change the loop to not use 'i' */ for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++) @@ -384,10 +383,10 @@ int mysqld_show_column_types(THD *thd) protocol->store(sys_column_types[i].default_value, system_charset_info); protocol->store(sys_column_types[i].comment, system_charset_info); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -486,7 +485,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, Extended version of mysqld_show_tables ***************************************************************************/ -int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) +bool mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) { Item *item; List files; @@ -496,7 +495,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) TABLE *table; Protocol *protocol= thd->protocol; TIME time; - int res; + bool res; DBUG_ENTER("mysqld_extend_show_tables"); (void) sprintf(path,"%s/%s",mysql_data_home,db); @@ -537,11 +536,9 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) field_list.push_back(item=new Item_empty_string("Comment",80)); item->maybe_null=1; if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - if (mysql_find_files(thd,&files,db,path,wild,0)) - DBUG_RETURN(-1); + Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF) || + mysql_find_files(thd,&files,db,path,wild,0)) + DBUG_RETURN(TRUE); List_iterator_fast it(files); while ((file_name=it++)) { @@ -558,14 +555,12 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) { for (uint i=2 ; i < field_list.elements ; i++) protocol->store_null(); - // Send error to Comment field if possible - if (res < 0) + // Send error to Comment field + if (res) { protocol->store(thd->net.last_error, system_charset_info); thd->clear_error(); } - else - DBUG_RETURN(1); } else if (table_list.view) { @@ -680,10 +675,10 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) } close_thread_tables(thd, 0); if (protocol->write()) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -691,7 +686,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) ** List all columns in a table_list->real_name ***************************************************************************/ -int +bool mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, bool verbose) { @@ -707,11 +702,9 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, table_list->real_name)); table_list->lock_type= TL_UNLOCK; - if ((res= open_and_lock_tables(thd, table_list))) + if (open_and_lock_tables(thd, table_list)) { - if (res < 0) - send_error(thd); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } table= table_list->table; file=table->file; @@ -737,7 +730,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, // Send first number of fields and records if (protocol->send_records_num(&field_list, (ulonglong)file->records) || protocol->send_fields(&field_list, Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); restore_record(table,default_values); // Get empty record Field **ptr,*field; @@ -844,16 +837,16 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, system_charset_info); } if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } -int +bool mysqld_show_create(THD *thd, TABLE_LIST *table_list) { TABLE *table; @@ -866,18 +859,16 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) table_list->real_name)); /* Only one table for now, but VIEW can involve several tables */ - if ((res= open_and_lock_tables(thd, table_list))) + if (open_and_lock_tables(thd, table_list)) { - if (res < 0) - send_error(thd); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } /* TODO: add environment variables show when it become possible */ if (thd->lex->only_view && !table_list->view) { my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, table_list->real_name, "VIEW"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } table= table_list->table; @@ -885,7 +876,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if ((table_list->view ? view_store_create_info(thd, table_list, &buffer) : store_create_info(thd, table, &buffer))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); List field_list; if (table_list->view) @@ -904,31 +895,31 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); buffer.length(0); if (table_list->view) { protocol->store(table_list->view_name.str, system_charset_info); if (view_store_create_info(thd, table_list, &buffer)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } else { protocol->store(table->table_name, system_charset_info); if (store_create_info(thd, table, &buffer)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } -int mysqld_show_create_db(THD *thd, char *dbname, - HA_CREATE_INFO *create_info) +bool mysqld_show_create_db(THD *thd, char *dbname, + HA_CREATE_INFO *create_info) { int length; char path[FN_REFLEN]; @@ -945,8 +936,8 @@ int mysqld_show_create_db(THD *thd, char *dbname, if (check_db_name(dbname)) { - net_printf(thd,ER_WRONG_DB_NAME, dbname); - DBUG_RETURN(1); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); + DBUG_RETURN(TRUE); } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -957,11 +948,11 @@ int mysqld_show_create_db(THD *thd, char *dbname, thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - net_printf(thd,ER_DBACCESS_DENIED_ERROR, - thd->priv_user, thd->host_or_ip, dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, thd->host_or_ip, dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->host_or_ip, dbname); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } #endif @@ -975,8 +966,8 @@ int mysqld_show_create_db(THD *thd, char *dbname, } if (access(path,F_OK)) { - net_printf(thd,ER_BAD_DB_ERROR,dbname); - DBUG_RETURN(1); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); + DBUG_RETURN(TRUE); } if (found_libchar) path[length-1]= FN_LIBCHAR; @@ -989,7 +980,7 @@ int mysqld_show_create_db(THD *thd, char *dbname, if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); protocol->prepare_for_resend(); protocol->store(dbname, strlen(dbname), system_charset_info); @@ -1014,12 +1005,12 @@ int mysqld_show_create_db(THD *thd, char *dbname, protocol->store(buffer.ptr(), buffer.length(), buffer.charset()); if (protocol->write()) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } -int +bool mysqld_show_logs(THD *thd) { List field_list; @@ -1032,19 +1023,19 @@ mysqld_show_logs(THD *thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); #ifdef HAVE_BERKELEY_DB if ((have_berkeley_db == SHOW_OPTION_YES) && berkeley_show_logs(protocol)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); #endif send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } -int +bool mysqld_show_keys(THD *thd, TABLE_LIST *table_list) { TABLE *table; @@ -1055,8 +1046,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) { - send_error(thd); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } List field_list; @@ -1082,7 +1072,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); KEY *key_info=table->key_info; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); @@ -1133,11 +1123,11 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) else protocol->store("", 0, system_charset_info); if (protocol->write()) - DBUG_RETURN(1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -1155,12 +1145,8 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) DBUG_PRINT("enter",("table: %s",table_list->real_name)); table_list->lock_type= TL_UNLOCK; - if ((res= open_and_lock_tables(thd, table_list))) - { - if (res < 0) - send_error(thd); + if (open_and_lock_tables(thd, table_list)) DBUG_VOID_RETURN; - } table= table_list->table; List field_list; @@ -1805,7 +1791,7 @@ static bool write_collation(Protocol *protocol, CHARSET_INFO *cs) return protocol->write(); } -int mysqld_show_collations(THD *thd, const char *wild) +bool mysqld_show_collations(THD *thd, const char *wild) { char buff[8192]; String packet2(buff,sizeof(buff),thd->charset()); @@ -1813,7 +1799,7 @@ int mysqld_show_collations(THD *thd, const char *wild) CHARSET_INFO **cs; Protocol *protocol= thd->protocol; - DBUG_ENTER("mysqld_show_charsets"); + DBUG_ENTER(" mysqld_show_collations"); field_list.push_back(new Item_empty_string("Collation",30)); field_list.push_back(new Item_empty_string("Charset",30)); @@ -1824,7 +1810,7 @@ int mysqld_show_collations(THD *thd, const char *wild) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) { @@ -1845,10 +1831,10 @@ int mysqld_show_collations(THD *thd, const char *wild) } } } - send_eof(thd); - DBUG_RETURN(0); + send_eof(thd); + DBUG_RETURN(FALSE); err: - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } static bool write_charset(Protocol *protocol, CHARSET_INFO *cs) @@ -1861,7 +1847,7 @@ static bool write_charset(Protocol *protocol, CHARSET_INFO *cs) return protocol->write(); } -int mysqld_show_charsets(THD *thd, const char *wild) +bool mysqld_show_charsets(THD *thd, const char *wild) { char buff[8192]; String packet2(buff,sizeof(buff),thd->charset()); @@ -1878,7 +1864,7 @@ int mysqld_show_charsets(THD *thd, const char *wild) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) { @@ -1891,18 +1877,18 @@ int mysqld_show_charsets(THD *thd, const char *wild) goto err; } } - send_eof(thd); - DBUG_RETURN(0); + send_eof(thd); + DBUG_RETURN(FALSE); err: - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } -int mysqld_show(THD *thd, const char *wild, show_var_st *variables, - enum enum_var_type value_type, - pthread_mutex_t *mutex, - struct system_status_var *status_var) +bool mysqld_show(THD *thd, const char *wild, show_var_st *variables, + enum enum_var_type value_type, + pthread_mutex_t *mutex, + struct system_status_var *status_var) { char buff[1024]; List field_list; @@ -1914,7 +1900,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, field_list.push_back(new Item_empty_string("Value",256)); if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ null_lex_str.str= 0; // For sys_var->value_ptr() null_lex_str.length= 0; @@ -2206,11 +2192,11 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, } pthread_mutex_unlock(mutex); send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: pthread_mutex_unlock(mutex); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 399fed00040..d84611ae496 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -57,15 +57,15 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set. RETURN - 0 ok. In this case ok packet is sent to user - -1 Error (Error message given but not sent to user) + FALSE OK. In this case ok packet is sent to user + TRUE Error */ -int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, - my_bool drop_temporary) +bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, + my_bool drop_temporary) { - int error= 0; + bool error= FALSE; DBUG_ENTER("mysql_rm_table"); /* mark for close and remove all cached entries */ @@ -80,7 +80,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, { my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0), tables->real_name); - error= 1; + error= TRUE; goto err; } while (global_read_lock && ! thd->killed) @@ -100,9 +100,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, pthread_mutex_unlock(&thd->mysys_var->mutex); if (error) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -1101,22 +1101,22 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, and must be zero for standard create of table. RETURN VALUES - 0 ok - -1 error + FALSE OK + TRUE error */ -int mysql_create_table(THD *thd,const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List &fields, - List &keys,bool tmp_table, - uint select_field_count) +bool mysql_create_table(THD *thd,const char *db, const char *table_name, + HA_CREATE_INFO *create_info, + List &fields, + List &keys,bool tmp_table, + uint select_field_count) { char path[FN_REFLEN]; const char *alias; - int error= -1; uint db_options, key_count; KEY *key_info_buffer; handler *file; + bool error= TRUE; enum db_type new_db_type; DBUG_ENTER("mysql_create_table"); @@ -1124,7 +1124,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (!fields.elements) { my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if ((new_db_type= ha_checktype(create_info->db_type)) != create_info->db_type) @@ -1154,7 +1154,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, (file->table_flags() & HA_NO_TEMP_TABLES)) { my_error(ER_ILLEGAL_HA,MYF(0),table_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } #endif @@ -1179,7 +1179,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, keys, tmp_table, db_options, file, key_info_buffer, &key_count, select_field_count)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Check if table exists */ if (create_info->options & HA_LEX_CREATE_TMP_TABLE) @@ -1202,10 +1202,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { create_info->table_existed= 1; // Mark that table existed - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (wait_if_global_read_lock(thd, 0, 1)) DBUG_RETURN(error); @@ -1217,7 +1217,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { create_info->table_existed= 1; // Mark that table existed - error= 0; + error= FALSE; } else my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); @@ -1246,7 +1246,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (create_if_not_exists) { create_info->table_existed= 1; // Mark that table existed - error= 0; + error= FALSE; } else my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); @@ -1285,7 +1285,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } - error=0; + error= FALSE; end: VOID(pthread_mutex_unlock(&LOCK_open)); start_waiting_global_read_lock(thd); @@ -1547,7 +1547,7 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table, protocol->store((char*) operator_name, system_charset_info); protocol->store("error", 5, system_charset_info); protocol->store(errmsg, system_charset_info); - thd->net.last_error[0]=0; + thd->clear_error(); if (protocol->write()) return -1; return 1; @@ -1722,16 +1722,16 @@ end: } -static int mysql_admin_table(THD* thd, TABLE_LIST* tables, - HA_CHECK_OPT* check_opt, - const char *operator_name, - thr_lock_type lock_type, - bool open_for_modify, - uint extra_open_options, - int (*prepare_func)(THD *, TABLE_LIST *, - HA_CHECK_OPT *), - int (handler::*operator_func) - (THD *, HA_CHECK_OPT *)) +static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, + HA_CHECK_OPT* check_opt, + const char *operator_name, + thr_lock_type lock_type, + bool open_for_modify, + uint extra_open_options, + int (*prepare_func)(THD *, TABLE_LIST *, + HA_CHECK_OPT *), + int (handler::*operator_func) + (THD *, HA_CHECK_OPT *)) { TABLE_LIST *table; List field_list; @@ -1749,7 +1749,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, item->maybe_null = 1; if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); mysql_ha_close(thd, tables, /*dont_send_ok*/ 1, /*dont_lock*/ 1); for (table= tables; table; table= table->next_local) @@ -1761,9 +1761,6 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, thd->open_options|= extra_open_options; table->table = open_ltable(thd, table, lock_type); -#ifdef EMBEDDED_LIBRARY - thd->net.last_errno= 0; // these errors shouldn't get client -#endif thd->open_options&= ~extra_open_options; if (prepare_func) @@ -1785,7 +1782,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (!(err_msg=thd->net.last_error)) err_msg=ER(ER_CHECK_NO_SUCH_TABLE); protocol->store(err_msg, system_charset_info); - thd->net.last_error[0]=0; + thd->clear_error(); if (protocol->write()) goto err; continue; @@ -1829,9 +1826,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, } int result_code = (table->table->file->*operator_func)(thd, check_opt); -#ifdef EMBEDDED_LIBRARY - thd->net.last_errno= 0; // these errors shouldn't get client -#endif + thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); protocol->store(operator_name, system_charset_info); @@ -1932,16 +1927,16 @@ send_result_message: } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } -int mysql_backup_table(THD* thd, TABLE_LIST* table_list) +bool mysql_backup_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_backup_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, @@ -1950,7 +1945,7 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list) } -int mysql_restore_table(THD* thd, TABLE_LIST* table_list) +bool mysql_restore_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_restore_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, @@ -1960,7 +1955,7 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list) } -int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, @@ -1970,7 +1965,7 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) } -int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_optimize_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, @@ -1988,11 +1983,11 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + FALSE ok + TRUE error */ -int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, +bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, LEX_STRING *key_cache_name) { HA_CHECK_OPT check_opt; @@ -2005,7 +2000,7 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, { pthread_mutex_unlock(&LOCK_global_system_variables); my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } pthread_mutex_unlock(&LOCK_global_system_variables); check_opt.key_cache= key_cache; @@ -2063,11 +2058,11 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + FALSE ok + TRUE error */ -int mysql_preload_keys(THD* thd, TABLE_LIST* tables) +bool mysql_preload_keys(THD* thd, TABLE_LIST* tables) { DBUG_ENTER("mysql_preload_keys"); DBUG_RETURN(mysql_admin_table(thd, tables, 0, @@ -2087,13 +2082,13 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables) table_ident Src table_ident RETURN VALUES - 0 ok - -1 error + FALSE OK + TRUE error */ -int mysql_create_like_table(THD* thd, TABLE_LIST* table, - HA_CREATE_INFO *create_info, - Table_ident *table_ident) +bool mysql_create_like_table(THD* thd, TABLE_LIST* table, + HA_CREATE_INFO *create_info, + Table_ident *table_ident) { TABLE **tmp_table; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; @@ -2101,7 +2096,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, char *table_name= table->real_name; char *src_db= thd->db; char *src_table= table_ident->table.str; - int err, res= -1; + int err; + bool res= TRUE; TABLE_LIST src_tables_list; DBUG_ENTER("mysql_create_like_table"); @@ -2114,7 +2110,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, table_ident->db.str && check_db_name((src_db= table_ident->db.str))) { my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } bzero((gptr)&src_tables_list, sizeof(src_tables_list)); @@ -2201,7 +2197,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } - res= 0; + res= FALSE; goto err; table_exists: @@ -2212,7 +2208,7 @@ table_exists: ER(ER_TABLE_EXISTS_ERROR), table_name); push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_TABLE_EXISTS_ERROR,warn_buff); - res= 0; + res= FALSE; } else my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); @@ -2225,7 +2221,7 @@ err: } -int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) +bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { #ifdef OS2 thr_lock_type lock_type = TL_WRITE; @@ -2240,7 +2236,7 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) } -int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) +bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) { #ifdef OS2 thr_lock_type lock_type = TL_WRITE; @@ -2528,13 +2524,13 @@ int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list, Alter table */ -int mysql_alter_table(THD *thd,char *new_db, char *new_name, - HA_CREATE_INFO *create_info, - TABLE_LIST *table_list, - List &fields, List &keys, - uint order_num, ORDER *order, - enum enum_duplicates handle_duplicates, - ALTER_INFO *alter_info, bool do_send_ok) +bool mysql_alter_table(THD *thd,char *new_db, char *new_name, + HA_CREATE_INFO *create_info, + TABLE_LIST *table_list, + List &fields, List &keys, + uint order_num, ORDER *order, + enum enum_duplicates handle_duplicates, + ALTER_INFO *alter_info, bool do_send_ok) { TABLE *table,*new_table; int error; @@ -2563,7 +2559,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, alter_info->tablespace_op)); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Check that we are not trying to rename to an existing table */ if (new_name) @@ -2595,7 +2591,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (find_temporary_table(thd,new_db,new_name_buff)) { my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } else @@ -2605,7 +2601,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { /* Table will be closed in do_command() */ my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -2788,7 +2784,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (def->sql_type == FIELD_TYPE_BLOB) { my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } def->def=alter->def; // Use new default alter_it.remove(); @@ -2802,7 +2798,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (def->change && ! def->field) { my_error(ER_BAD_FIELD_ERROR,MYF(0),def->change,table_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!def->after) create_list.push_back(def); @@ -2820,7 +2816,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!find) { my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } find_it.after(def); // Put element after this } @@ -2829,12 +2825,12 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { my_error(ER_BAD_FIELD_ERROR,MYF(0),alter_info->alter_list.head()->name, table_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!create_list.elements) { my_error(ER_CANT_REMOVE_ALL_FIELDS,MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -2923,7 +2919,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -3261,10 +3257,10 @@ end_temporary: if (do_send_ok) send_ok(thd,copied+deleted,0L,tmp_name); thd->some_tables_deleted=0; - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } @@ -3433,8 +3429,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, RETURN Like mysql_alter_table(). */ -int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, - bool do_send_ok) +bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, + bool do_send_ok) { DBUG_ENTER("mysql_recreate_table"); LEX *lex= thd->lex; @@ -3455,7 +3451,7 @@ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list, } -int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) +bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { TABLE_LIST *table; List field_list; @@ -3469,7 +3465,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) item->maybe_null= 1; if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); for (table= tables; table; table= table->next_local) { @@ -3488,7 +3484,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) { /* Table didn't exist */ protocol->store_null(); - thd->net.last_error[0]=0; + thd->clear_error(); } else { @@ -3550,11 +3546,11 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) } send_eof(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index add4078ce8e..b71bb4ba42a 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -38,12 +38,13 @@ static File_option triggers_file_parameters[]= methods. RETURN VALUE - 0 - Success, non-0 in case of error. + FALSE Success + TRUE error */ -int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) +bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) { TABLE *table; - int result= 0; + bool result= 0; DBUG_ENTER("mysql_create_or_drop_trigger"); @@ -53,7 +54,7 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) */ if (open_and_lock_tables(thd, tables)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* TODO: We should check if user has TRIGGER privilege for table here. @@ -61,7 +62,7 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) we don't have proper privilege checking for triggers in place yet. */ if (check_global_access(thd, SUPER_ACL)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); table= tables->table; @@ -74,7 +75,7 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (tables->view || table->tmp_table != NO_TMP_TABLE) { my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!table->triggers) @@ -82,11 +83,11 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (!create) { my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!(table->triggers= new (&table->mem_root) Table_triggers_list())) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -96,12 +97,12 @@ int mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) global read lock is held without helding LOCK_open). */ if (wait_if_global_read_lock(thd, 0, 0)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); VOID(pthread_mutex_lock(&LOCK_open)); - if ((create ? table->triggers->create_trigger(thd, tables): - table->triggers->drop_trigger(thd, tables))) - result= -1; + result= (create ? + table->triggers->create_trigger(thd, tables): + table->triggers->drop_trigger(thd, tables)); /* It is sensible to invalidate table in any case */ close_cached_table(thd, table); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 561f79f9de1..d27b72c02a7 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -369,7 +369,7 @@ int mysql_create_function(THD *thd,udf_func *udf) if (!initialized) { - send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); + my_error(ER_OUT_OF_RESOURCES, MYF(0)); DBUG_RETURN(1); } @@ -380,19 +380,19 @@ int mysql_create_function(THD *thd,udf_func *udf) */ if (strchr(udf->dl, '/')) { - send_error(thd, ER_UDF_NO_PATHS,ER(ER_UDF_NO_PATHS)); + my_error(ER_UDF_NO_PATHS, MYF(0)); DBUG_RETURN(1); } if (udf->name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT,udf->name); + my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name); DBUG_RETURN(1); } rw_wrlock(&THR_LOCK_udf); if ((hash_search(&udf_hash,(byte*) udf->name.str, udf->name.length))) { - net_printf(thd, ER_UDF_EXISTS, udf->name); + my_error(ER_UDF_EXISTS, MYF(0), udf->name); goto err; } if (!(dl = find_udf_dl(udf->dl))) @@ -401,7 +401,7 @@ int mysql_create_function(THD *thd,udf_func *udf) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", udf->dl,errno,dlerror())); - net_printf(thd, ER_CANT_OPEN_LIBRARY, udf->dl, errno, dlerror()); + my_error(ER_CANT_OPEN_LIBRARY, MYF(0), udf->dl, errno, dlerror()); goto err; } new_dl=1; @@ -411,16 +411,13 @@ int mysql_create_function(THD *thd,udf_func *udf) if (udf->func == NULL) { - net_printf(thd, ER_CANT_FIND_DL_ENTRY, udf->name); + my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), udf->name); goto err; } udf->name.str=strdup_root(&mem,udf->name.str); udf->dl=strdup_root(&mem,udf->dl); if (!(u_d=add_udf(&udf->name,udf->returns,udf->dl,udf->type))) - { - send_error(thd,0); // End of memory goto err; - } u_d->dlhandle = dl; u_d->func=udf->func; u_d->func_init=udf->func_init; @@ -448,7 +445,7 @@ int mysql_create_function(THD *thd,udf_func *udf) close_thread_tables(thd); if (error) { - net_printf(thd, ER_ERROR_ON_WRITE, "func@mysql",error); + my_error(ER_ERROR_ON_WRITE, MYF(0), "func@mysql", error); del_udf(u_d); goto err; } @@ -471,14 +468,14 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) DBUG_ENTER("mysql_drop_function"); if (!initialized) { - send_error(thd, ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES)); + my_error(ER_OUT_OF_RESOURCES, MYF(0)); DBUG_RETURN(1); } rw_wrlock(&THR_LOCK_udf); if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name->str, (uint) udf_name->length))) { - net_printf(thd, ER_FUNCTION_NOT_DEFINED, udf_name->str); + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), udf_name->str); goto err; } del_udf(udf); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index cf4203bf5b8..6a2d11ba7f5 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -24,21 +24,20 @@ #include "mysql_priv.h" #include "sql_select.h" -int mysql_union(THD *thd, LEX *lex, select_result *result, - SELECT_LEX_UNIT *unit) +bool mysql_union(THD *thd, LEX *lex, select_result *result, + SELECT_LEX_UNIT *unit) { DBUG_ENTER("mysql_union"); - int res, res_cln; + bool res; if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK))) res= unit->exec(); - if (res == 0 && thd->cursor && thd->cursor->is_open()) + if (!res && thd->cursor && thd->cursor->is_open()) { thd->cursor->set_unit(unit); - res_cln= 0; } else - res_cln= unit->cleanup(); - DBUG_RETURN(res?res:res_cln); + res|= unit->cleanup(); + DBUG_RETURN(res); } @@ -104,8 +103,7 @@ bool select_union::flush() int error; if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) { - table->file->print_error(error,MYF(0)); - ::send_error(thd); + table->file->print_error(error, MYF(0)); return 1; } return 0; @@ -147,8 +145,8 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd) } -int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, - ulong additional_options) +bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, + ulong additional_options) { SELECT_LEX *lex_select_save= thd_arg->lex->current_select; SELECT_LEX *sl, *first_select; @@ -176,16 +174,16 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (!sl->join->procedure && result->prepare(sl->join->fields_list, this)) { - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } sl->join->select_options|= SELECT_DESCRIBE; sl->join->reinit(); } } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } prepared= 1; - res= 0; + res= FALSE; thd_arg->lex->current_select= sl= first_select= first_select_in_union(); found_rows_for_union= first_select->options & OPTION_FOUND_ROWS; @@ -232,7 +230,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, sl->having, (ORDER*) NULL, sl, this); - if (res || thd_arg->is_fatal_error) + if ((res= (res || thd_arg->is_fatal_error))) goto err; if (sl == first_select) { @@ -262,7 +260,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, while ((type= tp++, item_tmp= it++)) { if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -305,7 +303,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { if (arena) thd->restore_backup_item_arena(arena, &backup); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } if (arena) @@ -323,7 +321,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, result))) { fake_select_lex->table_list.empty(); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } fake_select_lex->item_list= item_list; @@ -345,15 +343,15 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, thd_arg->lex->current_select= lex_select_save; - DBUG_RETURN(res || thd_arg->is_fatal_error ? 1 : 0); + DBUG_RETURN(res || thd_arg->is_fatal_error); err: thd_arg->lex->current_select= lex_select_save; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } -int st_select_lex_unit::exec() +bool st_select_lex_unit::exec() { SELECT_LEX *lex_select_save= thd->lex->current_select; SELECT_LEX *select_cursor=first_select_in_union(); @@ -361,7 +359,7 @@ int st_select_lex_unit::exec() DBUG_ENTER("st_select_lex_unit::exec"); if (executed && !uncacheable && !describe) - DBUG_RETURN(0); + DBUG_RETURN(FALSE); executed= 1; if (uncacheable || !item || !item->assigned() || describe) @@ -376,7 +374,7 @@ int st_select_lex_unit::exec() } /* re-enabling indexes for next subselect iteration */ if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL)) - DBUG_ASSERT(1); + DBUG_ASSERT(TRUE); } for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { @@ -431,7 +429,7 @@ int st_select_lex_unit::exec() if (sl == union_distinct) { if (table->file->disable_indexes(HA_KEY_SWITCH_ALL)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); table->no_keyread=1; } res= sl->join->error; @@ -439,7 +437,7 @@ int st_select_lex_unit::exec() if (!res && union_result->flush()) { thd->lex->current_select= lex_select_save; - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } } if (res) @@ -465,7 +463,7 @@ int st_select_lex_unit::exec() optimized= 1; /* Send result to 'result' */ - res= -1; + res= TRUE; { List empty_list; empty_list.empty(); @@ -484,7 +482,7 @@ int st_select_lex_unit::exec() fake_select_lex->options, result))) { fake_select_lex->table_list.empty(); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -528,7 +526,7 @@ int st_select_lex_unit::exec() } -int st_select_lex_unit::cleanup() +bool st_select_lex_unit::cleanup() { int error= 0; JOIN *join; @@ -536,7 +534,7 @@ int st_select_lex_unit::cleanup() if (cleaned) { - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } cleaned= 1; @@ -610,19 +608,19 @@ void st_select_lex_unit::reinit_exec_mechanism() old_result old select_result object RETURN - 0 - OK - -1 - error + FALSE - OK + TRUE - error */ -int st_select_lex_unit::change_result(select_subselect *result, - select_subselect *old_result) +bool st_select_lex_unit::change_result(select_subselect *result, + select_subselect *old_result) { - int res= 0; + bool res= FALSE; for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select()) { if (sl->join && sl->join->result == old_result) - if ((res= sl->join->change_result(result))) - return (res); + if (sl->join->change_result(result)) + return TRUE; } if (fake_select_lex && fake_select_lex->join) res= fake_select_lex->join->change_result(result); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 00e70ccb484..8d64d30a9e0 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -87,21 +87,21 @@ static bool check_fields(THD *thd, List &items) } -int mysql_update(THD *thd, - TABLE_LIST *table_list, - List &fields, - List &values, - COND *conds, - uint order_num, ORDER *order, - ha_rows limit, - enum enum_duplicates handle_duplicates) +bool mysql_update(THD *thd, + TABLE_LIST *table_list, + List &fields, + List &values, + COND *conds, + uint order_num, ORDER *order, + ha_rows limit, + enum enum_duplicates handle_duplicates) { bool using_limit= limit != HA_POS_ERROR; bool safe_update= thd->options & OPTION_SAFE_UPDATES; bool used_key_is_modified, transactional_table, log_delayed; bool ignore_err= (thd->lex->duplicates == DUP_IGNORE); + bool res; int error=0; - int res; uint used_index; #ifndef NO_EMBEDDED_ACCESS_CHECKS uint want_privilege; @@ -117,8 +117,8 @@ int mysql_update(THD *thd, LINT_INIT(used_index); LINT_INIT(timestamp_query_id); - if ((error= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(error); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); thd->proc_info="init"; table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); @@ -156,16 +156,16 @@ int mysql_update(THD *thd, res= setup_fields(thd, 0, table_list, fields, 1, 0, 0); thd->lex->select_lex.no_wrap_view_item= 0; if (res) - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } if (table_list->view && check_fields(thd, fields)) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (!table_list->updatable || check_key_in_view(thd, table_list)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } if (table->timestamp_field) { @@ -184,7 +184,7 @@ int mysql_update(THD *thd, if (setup_fields(thd, 0, table_list, values, 0, 0, 0)) { free_underlaid_joins(thd, &thd->lex->select_lex); - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(TRUE); /* purecov: inspected */ } // Don't count on usage of 'only index' when calculating which key to use @@ -197,10 +197,10 @@ int mysql_update(THD *thd, free_underlaid_joins(thd, &thd->lex->select_lex); if (error) { - DBUG_RETURN(-1); // Error in where + DBUG_RETURN(TRUE); // Error in where } send_ok(thd); // No matching records - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } /* If running in safe sql mode, don't allow updates without keys */ if (table->quick_keys.is_clear_all()) @@ -363,7 +363,15 @@ int mysql_update(THD *thd, { store_record(table,record[1]); if (fill_record(fields,values, 0) || thd->net.report_error) + { + /* Field::store methods can't send errors */ + if (!thd->net.report_error) + { + /* TODO: convert last warning to error */ + my_error(ER_UNKNOWN_ERROR, MYF(0)); + } break; /* purecov: inspected */ + } found++; if (table->triggers) @@ -456,9 +464,7 @@ int mysql_update(THD *thd, } free_underlaid_joins(thd, &thd->lex->select_lex); - if (error >= 0) - send_error(thd,thd->killed_errno()); /* purecov: inspected */ - else + if (error < 0) { char buff[80]; sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, @@ -472,7 +478,7 @@ int mysql_update(THD *thd, thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ thd->abort_on_warning= 0; free_io_cache(table); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: delete select; @@ -483,7 +489,7 @@ err: table->file->extra(HA_EXTRA_NO_KEYREAD); } thd->abort_on_warning= 0; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* @@ -555,11 +561,11 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, thd thread handler RETURN - 0 OK - -1 Error + FALSE OK + TRUE Error */ -int mysql_multi_update_prepare(THD *thd) +bool mysql_multi_update_prepare(THD *thd) { LEX *lex= thd->lex; TABLE_LIST *table_list= lex->query_tables; @@ -597,7 +603,7 @@ int mysql_multi_update_prepare(THD *thd) res= setup_fields(thd, 0, table_list, *fields, 1, 0, 0), thd->lex->select_lex.no_wrap_view_item= 0, res)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); for (tl= table_list; tl ; tl= tl->next_local) { @@ -610,7 +616,7 @@ int mysql_multi_update_prepare(THD *thd) if (update_view && check_fields(thd, *fields)) { - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } { @@ -650,36 +656,36 @@ int mysql_multi_update_prepare(THD *thd) (tables_for_update & tl->table->map)) { my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE"); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } - DBUG_RETURN (0); + DBUG_RETURN(FALSE); } -int mysql_multi_update(THD *thd, - TABLE_LIST *table_list, - List *fields, - List *values, - COND *conds, - ulong options, - enum enum_duplicates handle_duplicates, - SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) +bool mysql_multi_update(THD *thd, + TABLE_LIST *table_list, + List *fields, + List *values, + COND *conds, + ulong options, + enum enum_duplicates handle_duplicates, + SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) { - int res; + bool res; multi_update *result; DBUG_ENTER("mysql_multi_update"); - if ((res= open_and_lock_tables(thd, table_list))) - DBUG_RETURN(res); + if (open_and_lock_tables(thd, table_list)) + DBUG_RETURN(TRUE); if ((res= mysql_multi_update_prepare(thd))) DBUG_RETURN(res); if (!(result= new multi_update(thd, table_list, fields, values, handle_duplicates))) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); thd->no_trans_update= 0; thd->abort_on_warning= test(thd->variables.sql_mode & @@ -696,7 +702,7 @@ int mysql_multi_update(THD *thd, result, unit, select_lex); delete result; thd->abort_on_warning= 0; - DBUG_RETURN(res); + DBUG_RETURN(TRUE); } @@ -1023,7 +1029,15 @@ bool multi_update::send_data(List ¬_used_values) table->status|= STATUS_UPDATED; store_record(table,record[1]); if (fill_record(*fields_for_table[offset], *values_for_table[offset], 0)) + { + /* Field::store methods can't send errors */ + if (!thd->net.report_error) + { + /* TODO: convert last warning to error */ + my_error(ER_UNKNOWN_ERROR, MYF(0)); + } DBUG_RETURN(1); + } found++; if (compare_record(table, thd->query_id)) { @@ -1087,7 +1101,7 @@ bool multi_update::send_data(List ¬_used_values) void multi_update::send_error(uint errcode,const char *err) { /* First send error what ever it is ... */ - ::send_error(thd,errcode,err); + my_error(errcode, MYF(0), err); /* If nothing updated return */ if (!updated) @@ -1278,7 +1292,6 @@ bool multi_update::send_eof() /* Safety: If we haven't got an error before (should not happen) */ my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update", MYF(0)); - ::send_error(thd); return 1; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 4cdbfe9728b..7894287aee4 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -41,13 +41,12 @@ TYPELIB updatable_views_with_limit_typelib= mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE RETURN VALUE - 0 OK - -1 Error - 1 Error and error message given + FALSE OK + TRUE Error */ -int mysql_create_view(THD *thd, - enum_view_create_mode mode) +bool mysql_create_view(THD *thd, + enum_view_create_mode mode) { LEX *lex= thd->lex; bool link_to_local; @@ -57,7 +56,7 @@ int mysql_create_view(THD *thd, TABLE_LIST *tbl; SELECT_LEX *select_lex= &lex->select_lex, *sl; SELECT_LEX_UNIT *unit= &lex->unit; - int res= 0; + bool res= FALSE; DBUG_ENTER("mysql_create_view"); if (lex->proc_list.first || @@ -66,7 +65,7 @@ int mysql_create_view(THD *thd, my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), (lex->result ? "INTO" : "PROCEDURE")); - res= -1; + res= TRUE; goto err; } if (lex->derived_tables || @@ -75,7 +74,7 @@ int mysql_create_view(THD *thd, my_error((lex->derived_tables ? ER_VIEW_SELECT_DERIVED : ER_VIEW_SELECT_VARIABLE), MYF(0)); - res= -1; + res= TRUE; goto err; } @@ -101,7 +100,7 @@ int mysql_create_view(THD *thd, (check_access(thd, DELETE_ACL, view->db, &view->grant.privilege, 0, 0) || grant_option && check_grant(thd, DELETE_ACL, view, 0, 1, 0)))) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); for (sl= select_lex; sl; sl= sl->next_select()) { for (tbl= sl->get_table_list(); tbl; tbl= tbl->next_local) @@ -119,7 +118,7 @@ int mysql_create_view(THD *thd, thd->priv_user, thd->host_or_ip, tbl->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } /* Mark this table as a table which will be checked after the prepare @@ -155,7 +154,7 @@ int mysql_create_view(THD *thd, &tbl->grant.privilege, 0, 0) || grant_option && check_grant(thd, SELECT_ACL, tbl, 0, 1, 0)) { - res= 1; + res= TRUE; goto err; } } @@ -177,8 +176,8 @@ int mysql_create_view(THD *thd, } #endif - if ((res= open_and_lock_tables(thd, tables))) - DBUG_RETURN(res); + if (open_and_lock_tables(thd, tables)) + DBUG_RETURN(TRUE); /* check that tables are not temporary and this VIEW do not used in query @@ -190,7 +189,7 @@ int mysql_create_view(THD *thd, if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view) { my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias); - res= -1; + res= TRUE; goto err; } @@ -200,7 +199,7 @@ int mysql_create_view(THD *thd, strcmp(tbl->view_name.str, view->real_name) == 0) { my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str); - res= -1; + res= TRUE; goto err; } @@ -220,7 +219,7 @@ int mysql_create_view(THD *thd, some errors from prepare are reported to user, if is not then it will be checked after err: label */ - res= 1; + res= TRUE; goto err; } @@ -255,7 +254,7 @@ int mysql_create_view(THD *thd, if (strcmp(item->name, check->name) == 0) { my_error(ER_DUP_FIELDNAME, MYF(0), item->name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -294,7 +293,7 @@ int mysql_create_view(THD *thd, thd->host_or_ip, item->name, view->real_name); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } } } @@ -303,7 +302,7 @@ int mysql_create_view(THD *thd, if (wait_if_global_read_lock(thd, 0, 0)) { - res= -1; + res= TRUE; goto err; } VOID(pthread_mutex_lock(&LOCK_open)); @@ -321,9 +320,7 @@ err: thd->proc_info= "end"; lex->link_first_table_back(view, link_to_local); unit->cleanup(); - if (thd->net.report_error) - res= -1; - DBUG_RETURN(res); + DBUG_RETURN(res || thd->net.report_error); } @@ -824,12 +821,11 @@ err: drop_mode - cascade/check RETURN VALUE - 0 OK - -1 Error - 1 Error and error message given + FALSE OK + TRUE Error */ -int mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) +bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) { DBUG_ENTER("mysql_drop_view"); char path[FN_REFLEN]; @@ -865,11 +861,11 @@ int mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) VOID(pthread_mutex_unlock(&LOCK_open)); } send_ok(thd); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); err: VOID(pthread_mutex_unlock(&LOCK_open)); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } diff --git a/sql/sql_view.h b/sql/sql_view.h index 538f548d97b..4cb2514f5b9 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -16,12 +16,12 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -int mysql_create_view(THD *thd, - enum_view_create_mode mode); +bool mysql_create_view(THD *thd, + enum_view_create_mode mode); my_bool mysql_make_view(File_parser *parser, TABLE_LIST *table); -int mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode); +bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode); bool check_key_in_view(THD *thd, TABLE_LIST * view); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 31016b59c6f..fe25d689b4b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -810,7 +810,7 @@ query: if (!thd->bootstrap && (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) { - send_error(thd,ER_EMPTY_QUERY); + my_error(ER_EMPTY_QUERY, MYF(0)); YYABORT; } else @@ -1146,7 +1146,7 @@ create: if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "PROCEDURE"); + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE"); YYABORT; } /* Order is important here: new - reset - init */ @@ -1219,7 +1219,7 @@ create: if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "TRIGGER"); + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER"); YYABORT; } @@ -1300,7 +1300,7 @@ create_function_tail: if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "FUNCTION"); + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION"); YYABORT; } /* Order is important here: new - reset - init */ @@ -1455,7 +1455,7 @@ sp_fdparam: if (spc->find_pvar(&$1, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_PARAM, $1.str); + my_error(ER_SP_DUP_PARAM, MYF(0), $1.str); YYABORT; } spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); @@ -1481,7 +1481,7 @@ sp_pdparam: if (spc->find_pvar(&$2, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_PARAM, $2.str); + my_error(ER_SP_DUP_PARAM, MYF(0), $2.str); YYABORT; } spc->push_pvar(&$2, (enum enum_field_types)$3, @@ -1515,12 +1515,12 @@ sp_decls: better error handling this way.) */ if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs)) { /* Variable or condition following cursor or handler */ - send_error(YYTHD, ER_SP_VARCOND_AFTER_CURSHNDLR); + my_error(ER_SP_VARCOND_AFTER_CURSHNDLR, MYF(0)); YYABORT; } if ($2.curs && $1.hndlrs) { /* Cursor following handler */ - send_error(YYTHD, ER_SP_CURSOR_AFTER_HANDLER); + my_error(ER_SP_CURSOR_AFTER_HANDLER, MYF(0)); YYABORT; } $$.vars= $1.vars + $2.vars; @@ -1568,7 +1568,7 @@ sp_decl: if (spc->find_cond(&$2, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_COND, $2.str); + my_error(ER_SP_DUP_COND, MYF(0), $2.str); YYABORT; } YYTHD->lex->spcont->push_cond(&$2, $5); @@ -1625,7 +1625,7 @@ sp_decl: if (ctx->find_cursor(&$2, &offp, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_CURS, $2.str); + my_error(ER_SP_DUP_CURS, MYF(0), $2.str); delete $5; YYABORT; } @@ -1652,12 +1652,12 @@ sp_cursor_stmt: if (lex->sql_command != SQLCOM_SELECT) { - send_error(YYTHD, ER_SP_BAD_CURSOR_QUERY); + my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0)); YYABORT; } if (lex->result) { - send_error(YYTHD, ER_SP_BAD_CURSOR_SELECT); + my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0)); YYABORT; } lex->sp_lex_in_use= TRUE; @@ -1727,7 +1727,7 @@ sp_hcond: $$= Lex->spcont->find_cond(&$1); if ($$ == NULL) { - net_printf(YYTHD, ER_SP_COND_MISMATCH, $1.str); + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); YYABORT; } } @@ -1756,7 +1756,7 @@ sp_decl_idents: if (spc->find_pvar(&$1, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_VAR, $1.str); + my_error(ER_SP_DUP_VAR, MYF(0), $1.str); YYABORT; } spc->push_pvar(&$1, (enum_field_types)0, sp_param_in); @@ -1769,7 +1769,7 @@ sp_decl_idents: if (spc->find_pvar(&$3, TRUE)) { - net_printf(YYTHD, ER_SP_DUP_VAR, $3.str); + my_error(ER_SP_DUP_VAR, MYF(0), $3.str); YYABORT; } spc->push_pvar(&$3, (enum_field_types)0, sp_param_in); @@ -1802,7 +1802,7 @@ sp_proc_stmt: } if (lex->sql_command == SQLCOM_CHANGE_DB) { /* "USE db" doesn't work in a procedure */ - send_error(YYTHD, ER_SP_NO_USE); + my_error(ER_SP_NO_USE, MYF(0)); YYABORT; } /* Don't add an instruction for empty SET statements. @@ -1821,7 +1821,7 @@ sp_proc_stmt: */ if (sp->m_type != TYPE_ENUM_PROCEDURE) { - send_error(YYTHD, ER_SP_BADSTATEMENT); + my_error(ER_SP_BADSTATEMENT, MYF(0)); YYABORT; } else @@ -1851,7 +1851,7 @@ sp_proc_stmt: if (lex->sphead->m_type == TYPE_ENUM_PROCEDURE) { - send_error(YYTHD, ER_SP_BADRETURN); + my_error(ER_SP_BADRETURN, MYF(0)); YYABORT; } else @@ -1860,7 +1860,7 @@ sp_proc_stmt: if ($2->type() == Item::SUBSELECT_ITEM) { /* QQ For now, just disallow subselects as values */ - send_error(lex->thd, ER_SP_BADSTATEMENT); + my_error(ER_SP_BADSTATEMENT, MYF(0)); YYABORT; } i= new sp_instr_freturn(lex->sphead->instructions(), @@ -1923,7 +1923,7 @@ sp_proc_stmt: if (! lab) { - net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "LEAVE", $2.str); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str); YYABORT; } else @@ -1953,7 +1953,7 @@ sp_proc_stmt: if (! lab || lab->type != SP_LAB_ITER) { - net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE", $2.str); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str); YYABORT; } else @@ -1981,7 +1981,7 @@ sp_proc_stmt: if (lab) { - net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $2.str); + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str); YYABORT; } else @@ -2005,7 +2005,7 @@ sp_proc_stmt: if (sp->m_in_handler) { - send_error(lex->thd, ER_SP_GOTO_IN_HNDLR); + my_error(ER_SP_GOTO_IN_HNDLR, MYF(0)); YYABORT; } lab= ctx->find_label($2.str); @@ -2056,7 +2056,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); YYABORT; } i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); @@ -2071,7 +2071,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); YYABORT; } i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); @@ -2088,7 +2088,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); YYABORT; } i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); @@ -2106,7 +2106,7 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$1))) { - net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); YYABORT; } else @@ -2128,7 +2128,7 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$3))) { - net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $3.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str); YYABORT; } else @@ -2252,7 +2252,7 @@ sp_labeled_control: if (lab) { - net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $1.str); + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str); YYABORT; } else @@ -2273,7 +2273,7 @@ sp_labeled_control: if (!lab || my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) { - net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); + my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); YYABORT; } } @@ -2531,9 +2531,9 @@ default_charset: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - net_printf(YYTHD, ER_CONFLICTING_DECLARATIONS, - "CHARACTER SET ", cinfo->default_table_charset->csname, - "CHARACTER SET ", $4->csname); + my_error(ER_CONFLICTING_DECLARATIONS, MYF(0), + "CHARACTER SET ", cinfo->default_table_charset->csname, + "CHARACTER SET ", $4->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2548,8 +2548,8 @@ default_collation: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, - $4->name, cinfo->default_table_charset->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $4->name, cinfo->default_table_charset->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2561,7 +2561,7 @@ storage_engines: { $$ = ha_resolve_by_name($1.str,$1.length); if ($$ == DB_TYPE_UNKNOWN) { - net_printf(YYTHD, ER_UNKNOWN_STORAGE_ENGINE, $1.str); + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str); YYABORT; } }; @@ -2740,18 +2740,19 @@ type: $$=FIELD_TYPE_TINY_BLOB; } | BLOB_SYM opt_len { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_BLOB; } - | spatial_type { + | spatial_type + { #ifdef HAVE_SPATIAL - Lex->charset=&my_charset_bin; - Lex->uint_geom_type= (uint)$1; - $$=FIELD_TYPE_GEOMETRY; + Lex->charset=&my_charset_bin; + Lex->uint_geom_type= (uint)$1; + $$=FIELD_TYPE_GEOMETRY; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, - sym_group_geom.needed_define); - YYABORT; + my_error(ER_FEATURE_DISABLED, MYF(0) + sym_group_geom.name, + sym_group_geom.needed_define); + YYABORT; #endif - } + } | MEDIUMBLOB { Lex->charset=&my_charset_bin; $$=FIELD_TYPE_MEDIUM_BLOB; } | LONGBLOB { Lex->charset=&my_charset_bin; @@ -2915,8 +2916,8 @@ attribute: { if (Lex->charset && !my_charset_same(Lex->charset,$2)) { - net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, - $2->name,Lex->charset->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $2->name,Lex->charset->csname); YYABORT; } else @@ -2941,7 +2942,7 @@ charset_name: { if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) { - net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); YYABORT; } } @@ -2959,7 +2960,7 @@ old_or_new_charset_name: if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) && !($$=get_old_charset_by_name($1.str))) { - net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); YYABORT; } } @@ -2975,7 +2976,7 @@ collation_name: { if (!($$=get_charset_by_name($1.str,MYF(0)))) { - net_printf(YYTHD,ER_UNKNOWN_COLLATION,$1.str); + my_error(ER_UNKNOWN_COLLATION, MYF(0), $1.str); YYABORT; } }; @@ -2999,9 +3000,10 @@ opt_binary: | BYTE_SYM { Lex->charset=&my_charset_bin; } | UNICODE_SYM { - if (!(Lex->charset=get_charset_by_csname("ucs2",MY_CS_PRIMARY,MYF(0)))) + if (!(Lex->charset=get_charset_by_csname("ucs2", + MY_CS_PRIMARY,MYF(0)))) { - net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,"ucs2"); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2"); YYABORT; } } @@ -3063,8 +3065,8 @@ key_type: #ifdef HAVE_SPATIAL $$= Key::SPATIAL; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif }; @@ -3096,8 +3098,8 @@ opt_unique_or_fulltext: #ifdef HAVE_SPATIAL $$= Key::SPATIAL; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif } @@ -3324,7 +3326,7 @@ alter_list_item: if (check_table_name($3->table.str,$3->table.length) || $3->db.str && check_db_name($3->db.str)) { - net_printf(lex->thd,ER_WRONG_TABLE_NAME,$3->table.str); + my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); YYABORT; } lex->alter_info.flags|= ALTER_RENAME; @@ -3339,8 +3341,8 @@ alter_list_item: $5= $5 ? $5 : $4; if (!my_charset_same($4,$5)) { - net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, - $5->name,$4->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $5->name, $4->csname); YYABORT; } LEX *lex= Lex; @@ -3462,7 +3464,7 @@ slave_until: !((lex->mi.log_file_name && lex->mi.pos) || (lex->mi.relay_log_name && lex->mi.relay_log_pos))) { - send_error(lex->thd, ER_BAD_SLAVE_UNTIL_COND); + my_error(ER_BAD_SLAVE_UNTIL_COND, MYF(0)); YYABORT; } @@ -4175,9 +4177,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(void))($1.symbol->create_func))(); @@ -4186,9 +4188,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*))($1.symbol->create_func))($3); @@ -4197,9 +4199,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5); @@ -4208,9 +4210,9 @@ simple_expr: { if (!$1.symbol->create_func) { - net_printf(Lex->thd, ER_FEATURE_DISABLED, - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7); @@ -4311,8 +4313,8 @@ simple_expr: #ifdef HAVE_SPATIAL $$= $1; #else - net_printf(Lex->thd, ER_FEATURE_DISABLED, - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif } @@ -5168,12 +5170,12 @@ olap_opt: LEX *lex=Lex; if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) { - net_printf(lex->thd, ER_WRONG_USAGE, "WITH CUBE", + my_error(ER_WRONG_USAGE, MYF(0), "WITH CUBE", "global union parameters"); YYABORT; } lex->current_select->olap= CUBE_TYPE; - net_printf(lex->thd, ER_NOT_SUPPORTED_YET, "CUBE"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "CUBE"); YYABORT; /* To be deleted in 5.1 */ } | WITH ROLLUP_SYM @@ -5181,7 +5183,7 @@ olap_opt: LEX *lex= Lex; if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) { - net_printf(lex->thd, ER_WRONG_USAGE, "WITH ROLLUP", + my_error(ER_WRONG_USAGE, MYF(0), "WITH ROLLUP", "global union parameters"); YYABORT; } @@ -5205,9 +5207,8 @@ order_clause: lex->current_select->olap != UNSPECIFIED_OLAP_TYPE) { - net_printf(lex->thd, ER_WRONG_USAGE, - "CUBE/ROLLUP", - "ORDER BY"); + my_error(ER_WRONG_USAGE, MYF(0), + "CUBE/ROLLUP", "ORDER BY"); YYABORT; } } order_list; @@ -5305,9 +5306,7 @@ procedure_clause: LEX *lex=Lex; if (&lex->select_lex != lex->current_select) { - net_printf(lex->thd, ER_WRONG_USAGE, - "PROCEDURE", - "subquery"); + my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery"); YYABORT; } lex->proc_list.elements=0; @@ -5371,7 +5370,7 @@ select_var_ident: if (!lex->spcont || !(t=lex->spcont->find_pvar(&$1))) { - net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); YYABORT; } if (! lex->result) @@ -5466,7 +5465,7 @@ drop: LEX *lex=Lex; if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_DROP_SP, "FUNCTION"); + my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); YYABORT; } lex->sql_command = SQLCOM_DROP_FUNCTION; @@ -5478,7 +5477,7 @@ drop: LEX *lex=Lex; if (lex->sphead) { - net_printf(YYTHD, ER_SP_NO_DROP_SP, "PROCEDURE"); + my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE"); YYABORT; } lex->sql_command = SQLCOM_DROP_PROCEDURE; @@ -5726,8 +5725,8 @@ update: else if (lex->select_lex.get_table_list()->derived) { /* it is single table update and it is update of derived table */ - net_printf(lex->thd, ER_NON_UPDATABLE_TABLE, - lex->select_lex.get_table_list()->alias, "UPDATE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), + lex->select_lex.get_table_list()->alias, "UPDATE"); YYABORT; } } @@ -6049,7 +6048,7 @@ show_engine_param: Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS; break; default: - net_printf(YYTHD, ER_NOT_SUPPORTED_YET, "STATUS"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "STATUS"); YYABORT; } } @@ -6060,7 +6059,7 @@ show_engine_param: Lex->sql_command = SQLCOM_SHOW_LOGS; break; default: - net_printf(YYTHD, ER_NOT_SUPPORTED_YET, "LOGS"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "LOGS"); YYABORT; } }; @@ -6212,7 +6211,7 @@ purge_option: { if ($2->check_cols(1) || $2->fix_fields(Lex->thd, 0, &$2)) { - net_printf(Lex->thd, ER_WRONG_ARGUMENTS, "PURGE LOGS BEFORE"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); YYABORT; } Item *tmp= new Item_func_unix_timestamp($2); @@ -6234,7 +6233,7 @@ kill: LEX *lex=Lex; if ($3->fix_fields(lex->thd, 0, &$3) || $3->check_cols(1)) { - send_error(lex->thd, ER_SET_CONSTANTS_ONLY); + my_error(ER_SET_CONSTANTS_ONLY, MYF(0)); YYABORT; } lex->sql_command=SQLCOM_KILL; @@ -6381,7 +6380,7 @@ param_marker: (uchar *) thd->query)); if (!($$= item) || lex->param_list.push_back(item)) { - send_error(thd, ER_OUT_OF_RESOURCES); + my_error(ER_OUT_OF_RESOURCES, MYF(0)); YYABORT; } } @@ -6437,7 +6436,6 @@ NUM_literal: $$= new Item_real($1.str, $1.length); if (YYTHD->net.report_error) { - send_error(YYTHD, 0, NullS); YYABORT; } } @@ -6446,7 +6444,6 @@ NUM_literal: $$ = new Item_float($1.str, $1.length); if (YYTHD->net.report_error) { - send_error(YYTHD, 0, NullS); YYABORT; } } @@ -6541,16 +6538,14 @@ simple_ident_q: if (lex->trg_chistics.event == TRG_EVENT_INSERT && !new_row) { - net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "OLD", - "on INSERT"); + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT"); YYABORT; } if (lex->trg_chistics.event == TRG_EVENT_DELETE && new_row) { - net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "NEW", - "on DELETE"); + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE"); YYABORT; } @@ -6567,8 +6562,8 @@ simple_ident_q: FIXME. Far from perfect solution. See comment for "SET NEW.field_name:=..." for more info. */ - net_printf(YYTHD, ER_BAD_FIELD_ERROR, $3.str, - new_row ? "NEW": "OLD"); + my_error(ER_BAD_FIELD_ERROR, MYF(0), $3.str, + new_row ? "NEW": "OLD"); YYABORT; } @@ -6655,8 +6650,8 @@ IDENT_sys: $1.length); if (wlen < $1.length) { - net_printf(YYTHD, ER_INVALID_CHARACTER_STRING, cs->csname, - $1.str + wlen); + my_error(ER_INVALID_CHARACTER_STRING, MYF(0), cs->csname, + $1.str + wlen); YYABORT; } $$= $1; @@ -7034,7 +7029,7 @@ option_value: */ if (lex->query_tables) { - send_error(YYTHD, ER_SP_SUBSELECT_NYI); + my_error(ER_SP_SUBSELECT_NYI, MYF(0)); YYABORT; } sp_instr_set_user_var *i= @@ -7057,7 +7052,7 @@ option_value: sp_instr_set_trigger_field *i; if (lex->query_tables) { - send_error(YYTHD, ER_SP_SUBSELECT_NYI); + my_error(ER_SP_SUBSELECT_NYI, MYF(0)); YYABORT; } if ($3) @@ -7086,7 +7081,7 @@ option_value: Error message also should be improved. */ - net_printf(YYTHD, ER_BAD_FIELD_ERROR, $1.base_name, "NEW"); + my_error(ER_BAD_FIELD_ERROR, MYF(0), $1.base_name, "NEW"); YYABORT; } lex->sphead->add_instr(i); @@ -7152,7 +7147,8 @@ option_value: $3= $3 ? $3 : $2; if (!my_charset_same($2,$3)) { - net_printf(thd,ER_COLLATION_CHARSET_MISMATCH,$3->name,$2->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $3->name, $2->csname); YYABORT; } lex->var_list.push_back(new set_var_collation_client($3,$3,$3)); @@ -7218,18 +7214,18 @@ internal_variable_name: { if ($1.str[0]=='O' || $1.str[0]=='o') { - net_printf(YYTHD, ER_TRG_CANT_CHANGE_ROW, "OLD", ""); + my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "OLD", ""); YYABORT; } if (lex->trg_chistics.event == TRG_EVENT_DELETE) { - net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "NEW", - "on DELETE"); + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), + "NEW", "on DELETE"); YYABORT; } if (lex->trg_chistics.action_time == TRG_ACTION_AFTER) { - net_printf(YYTHD, ER_TRG_CANT_CHANGE_ROW, "NEW", "after "); + my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "NEW", "after "); YYABORT; } /* This special combination will denote field of NEW row */ @@ -7242,7 +7238,7 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); $$.var= tmp; $$.base_name= $1; } @@ -7253,7 +7249,7 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); $$.var= tmp; $$.base_name.str= (char*) "default"; $$.base_name.length= 7; @@ -7498,7 +7494,7 @@ require_list_element: LEX *lex=Lex; if (lex->x509_subject) { - net_printf(lex->thd,ER_DUP_ARGUMENT, "SUBJECT"); + my_error(ER_DUP_ARGUMENT, MYF(0), "SUBJECT"); YYABORT; } lex->x509_subject=$2.str; @@ -7508,7 +7504,7 @@ require_list_element: LEX *lex=Lex; if (lex->x509_issuer) { - net_printf(lex->thd,ER_DUP_ARGUMENT, "ISSUER"); + my_error(ER_DUP_ARGUMENT, MYF(0), "ISSUER"); YYABORT; } lex->x509_issuer=$2.str; @@ -7518,7 +7514,7 @@ require_list_element: LEX *lex=Lex; if (lex->ssl_cipher) { - net_printf(lex->thd,ER_DUP_ARGUMENT, "CIPHER"); + my_error(ER_DUP_ARGUMENT, MYF(0), "CIPHER"); YYABORT; } lex->ssl_cipher=$2.str; @@ -7534,7 +7530,7 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); + my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); YYABORT; } } @@ -7546,7 +7542,7 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); + my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); YYABORT; } } @@ -7558,7 +7554,7 @@ opt_table: lex->grant= GLOBAL_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - send_error(lex->thd,ER_ILLEGAL_GRANT_FOR_TABLE); + my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); YYABORT; } } @@ -7743,7 +7739,7 @@ union_list: if (lex->exchange) { /* Only the last SELECT can have INTO...... */ - net_printf(lex->thd, ER_WRONG_USAGE, "UNION", "INTO"); + my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO"); YYABORT; } if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) -- cgit v1.2.1 From e3b559938c1a739add9ad1dd2e5c62b8e10ade96 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 20 Oct 2004 16:06:54 +0300 Subject: changed function name to prevent injection wrong code from 4.1 (WL#2133) mysql-test/r/rpl_rotate_logs.result: changed error message mysql-test/t/rpl_rotate_logs.test: changed error message sql/log_event.cc: changed function name to prevent injection wrong code from 4.1 sql/mysqld.cc: changed function name to prevent injection wrong code from 4.1 sql/protocol.cc: changed function name to prevent injection wrong code from 4.1 sql/protocol.h: changed function name to prevent injection wrong code from 4.1 sql/sql_class.h: changed function name to prevent injection wrong code from 4.1 sql/sql_parse.cc: changed function name to prevent injection wrong code from 4.1 sql/sql_repl.cc: changed function name to prevent injection wrong code from 4.1 --- sql/log_event.cc | 2 +- sql/mysqld.cc | 4 ++-- sql/protocol.cc | 12 ++++++------ sql/protocol.h | 3 ++- sql/sql_class.h | 2 -- sql/sql_parse.cc | 53 ++++++++++++++++++++++++----------------------------- sql/sql_repl.cc | 4 ++-- 7 files changed, 37 insertions(+), 43 deletions(-) (limited to 'sql') diff --git a/sql/log_event.cc b/sql/log_event.cc index 01dcb2af21c..9c9e600edf0 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2587,7 +2587,7 @@ Slave: load data infile on table '%s' at log position %s in log \ my_afree(load_data_query); if (thd->query_error) { - /* this err/sql_errno code is copy-paste from send_error() */ + /* this err/sql_errno code is copy-paste from net_send_error() */ const char *err; int sql_errno; if ((err=thd->net.last_error)[0]) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c408478cb15..f2c235cac99 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1331,7 +1331,7 @@ void close_connection(THD *thd, uint errcode, bool lock) if ((vio=thd->net.vio) != 0) { if (errcode) - send_error(thd, errcode, ER(errcode)); /* purecov: inspected */ + net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */ vio_close(vio); /* vio is freed in delete thd */ } if (lock) @@ -3396,7 +3396,7 @@ static void create_new_thread(THD *thd) thd->killed= THD::KILL_CONNECTION; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); statistic_increment(aborted_connects,&LOCK_status); - net_printf(thd,ER_CANT_CREATE_THREAD,error); + net_printf_error(thd, ER_CANT_CREATE_THREAD, error); (void) pthread_mutex_lock(&LOCK_thread_count); close_connection(thd,0,0); delete thd; diff --git a/sql/protocol.cc b/sql/protocol.cc index c92d25f3f4d..b8414e45c97 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -53,14 +53,14 @@ bool Protocol_prep::net_store_data(const char *from, uint length) /* Send a error string to client */ -void send_error(THD *thd, uint sql_errno, const char *err) +void net_send_error(THD *thd, uint sql_errno, const char *err) { #ifndef EMBEDDED_LIBRARY uint length; char buff[MYSQL_ERRMSG_SIZE+2], *pos; #endif NET *net= &thd->net; - DBUG_ENTER("send_error"); + DBUG_ENTER("net_send_error"); DBUG_PRINT("enter",("sql_errno: %d err: %s", sql_errno, err ? err : net->last_error[0] ? net->last_error : "NULL")); @@ -169,7 +169,7 @@ void send_warning(THD *thd, uint sql_errno, const char *err) */ void -net_printf(THD *thd, uint errcode, ...) +net_printf_error(THD *thd, uint errcode, ...) { va_list args; uint length,offset; @@ -182,7 +182,7 @@ net_printf(THD *thd, uint errcode, ...) #endif NET *net= &thd->net; - DBUG_ENTER("net_printf"); + DBUG_ENTER("net_printf_error"); DBUG_PRINT("enter",("message: %u",errcode)); if (thd->spcont && thd->spcont->find_handler(errcode, @@ -196,8 +196,8 @@ net_printf(THD *thd, uint errcode, ...) #endif va_start(args,errcode); /* - The following is needed to make net_printf() work with 0 argument for - errorcode and use the argument after that as the format string. This + The following is needed to make net_printf_error() work with 0 argument + for errorcode and use the argument after that as the format string. This is useful for rare errors that are not worth the hassle to put in errmsg.sys, but at the same time, the message is not fixed text */ diff --git a/sql/protocol.h b/sql/protocol.h index 1a5896a3ae5..b65a666a5b1 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -172,7 +172,8 @@ public: }; void send_warning(THD *thd, uint sql_errno, const char *err=0); -void net_printf(THD *thd,uint sql_errno, ...); +void net_printf_error(THD *thd, uint sql_errno, ...); +void net_send_error(THD *thd, uint sql_errno=0, const char *err=0); void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L, const char *info=0); void send_eof(THD *thd, bool no_flush=0); diff --git a/sql/sql_class.h b/sql/sql_class.h index f014a597169..46cf8ca4899 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1196,8 +1196,6 @@ public: class JOIN; -void send_error(THD *thd, uint sql_errno=0, const char *err=0); - class select_result :public Sql_alloc { protected: THD *thd; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8817a29a705..ed174162db8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -165,7 +165,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, my_malloc(sizeof(struct user_conn) + temp_len+1, MYF(MY_WME))))) { - send_error(thd, 0, NullS); // Out of memory + net_send_error(thd, 0, NullS); // Out of memory return_val=1; goto end; } @@ -183,7 +183,7 @@ static int get_or_create_user_conn(THD *thd, const char *user, if (my_hash_insert(&hash_user_connections, (byte*) uc)) { my_free((char*) uc,0); - send_error(thd, 0, NullS); // Out of memory + net_send_error(thd, 0, NullS); // Out of memory return_val=1; goto end; } @@ -258,7 +258,7 @@ int check_user(THD *thd, enum enum_server_command command, */ if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323) { - net_printf(thd, ER_NOT_SUPPORTED_AUTH_MODE); + net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); mysql_log.write(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } @@ -290,8 +290,8 @@ int check_user(THD *thd, enum enum_server_command command, NET *net= &thd->net; if (opt_secure_auth_local) { - net_printf(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE, - thd->user, thd->host_or_ip); + net_printf_error(thd, ER_SERVER_IS_IN_SECURE_AUTH_MODE, + thd->user, thd->host_or_ip); mysql_log.write(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE), thd->user, thd->host_or_ip); DBUG_RETURN(-1); @@ -330,7 +330,7 @@ int check_user(THD *thd, enum enum_server_command command, VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (!count_ok) { // too many connections - send_error(thd, ER_CON_COUNT_ERROR); + net_send_error(thd, ER_CON_COUNT_ERROR); DBUG_RETURN(-1); } } @@ -380,14 +380,14 @@ int check_user(THD *thd, enum enum_server_command command, } else if (res == 2) // client gave short hash, server has long hash { - net_printf(thd, ER_NOT_SUPPORTED_AUTH_MODE); + net_printf_error(thd, ER_NOT_SUPPORTED_AUTH_MODE); mysql_log.write(thd,COM_CONNECT,ER(ER_NOT_SUPPORTED_AUTH_MODE)); DBUG_RETURN(-1); } - net_printf(thd, ER_ACCESS_DENIED_ERROR, - thd->user, - thd->host_or_ip, - passwd_len ? ER(ER_YES) : ER(ER_NO)); + net_printf_error(thd, ER_ACCESS_DENIED_ERROR, + thd->user, + thd->host_or_ip, + passwd_len ? ER(ER_YES) : ER(ER_NO)); mysql_log.write(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), thd->user, thd->host_or_ip, @@ -450,16 +450,16 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc) if (max_user_connections && max_user_connections < (uint) uc->connections) { - net_printf(thd,ER_TOO_MANY_USER_CONNECTIONS, uc->user); + net_printf_error(thd, ER_TOO_MANY_USER_CONNECTIONS, uc->user); error=1; goto end; } if (uc->user_resources.connections && uc->user_resources.connections <= uc->conn_per_hour) { - net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, - "max_connections", - (long) uc->user_resources.connections); + net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, + "max_connections", + (long) uc->user_resources.connections); error=1; goto end; } @@ -585,8 +585,8 @@ static bool check_mqh(THD *thd, uint check_command) if (uc->user_resources.questions && uc->questions++ >= uc->user_resources.questions) { - net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions", - (long) uc->user_resources.questions); + net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_questions", + (long) uc->user_resources.questions); error=1; goto end; } @@ -596,8 +596,8 @@ static bool check_mqh(THD *thd, uint check_command) if (uc->user_resources.updates && uc_update_queries[check_command] && uc->updates++ >= uc->user_resources.updates) { - net_printf(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates", - (long) uc->user_resources.updates); + net_printf_error(thd, ER_USER_LIMIT_REACHED, uc->user, "max_updates", + (long) uc->user_resources.updates); error=1; goto end; } @@ -1001,7 +1001,7 @@ pthread_handler_decl(handle_one_connection,arg) if ((error=check_connection(thd))) { // Wrong permissions if (error > 0) - net_printf(thd,error,thd->host_or_ip); + net_printf_error(thd, error, thd->host_or_ip); #ifdef __NT__ if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE) my_sleep(1000); /* must wait after eof() */ @@ -1044,7 +1044,7 @@ pthread_handler_decl(handle_one_connection,arg) thd->host_or_ip, (net->last_errno ? ER(net->last_errno) : ER(ER_UNKNOWN_ERROR))); - send_error(thd,net->last_errno,NullS); + net_send_error(thd, net->last_errno, NullS); statistic_increment(aborted_threads,&LOCK_status); } else if (thd->killed) @@ -1113,7 +1113,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) uint length=(uint) strlen(buff); if (buff[length-1]!='\n' && !feof(file)) { - send_error(thd,ER_NET_PACKET_TOO_LARGE, NullS); + net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS); thd->is_fatal_error= 1; break; } @@ -1267,7 +1267,7 @@ bool do_command(THD *thd) statistic_increment(aborted_threads,&LOCK_status); DBUG_RETURN(TRUE); // We have to close it. } - send_error(thd,net->last_errno,NullS); + net_send_error(thd, net->last_errno, NullS); net->error= 0; DBUG_RETURN(FALSE); } @@ -1808,7 +1808,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (thd->killed_errno() && !thd->net.report_error) thd->send_kill_message(); if (thd->is_fatal_error || thd->net.report_error) - send_error(thd); + net_send_error(thd); time_t start_of_query=thd->start_time; thd->end_time(); // Set start time @@ -3671,10 +3671,6 @@ create_error: goto error; #ifndef EMBEDDED_LIBRARY - /* - When executing substatements, they're assumed to send_error when - it happens, but not to send_ok. - */ my_bool nsok= thd->net.no_send_ok; thd->net.no_send_ok= TRUE; #endif @@ -3932,7 +3928,6 @@ create_error: DBUG_RETURN(res || thd->net.report_error); error: - /* We end up here if send_error() has already been done. */ DBUG_RETURN(TRUE); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index fe7e8432ec6..16daba09954 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -867,7 +867,7 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) if (slave_errno) { if (net_report) - send_error(thd, slave_errno); + my_error(slave_errno, MYF(0)); DBUG_RETURN(1); } else if (net_report) @@ -917,7 +917,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) if (slave_errno) { if (net_report) - send_error(thd, slave_errno); + my_error(slave_errno, MYF(0)); return 1; } else if (net_report) -- cgit v1.2.1 From 637c08d7cc0d462e445c68307d0c206fbf4f743b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Oct 2004 17:31:26 +0300 Subject: Implementation of WL#1972 "Evaluate HAVING before SELECT select-list" mysql-test/r/having.result: Added test of WL#1972 mysql-test/t/having.test: Added test of WL#1972 sql/item.cc: Name resolution for the HAVING clause searches non-aggregated GROUP BY columns. --- sql/item.cc | 296 ++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 229 insertions(+), 67 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 134b04d5540..b500d84ec4a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -26,6 +26,7 @@ #include "sql_acl.h" #include "sp_head.h" #include "sql_trigger.h" +#include "sql_select.h" static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, @@ -2261,55 +2262,207 @@ bool Item_field::send(Protocol *protocol, String *buffer) return protocol->store(result_field); } + /* - This is used for HAVING clause - Find field in select list having the same name - */ + Search a GROUP BY clause for a field with a certain name. + + SYNOPSIS + find_field_in_group_list() + find_item the item being searched for + group_list GROUP BY clause + + DESCRIPTION + Search the GROUP BY list for a column named as find_item. When searching + preference is given to columns that are qualified with the same table (and + database) name as the one being searched for. + + RETURN + - the found item on success + - NULL if find_item is not in group_list +*/ + +static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) +{ + const char *db_name; + const char *table_name; + const char *field_name; + ORDER *found_group= NULL; + int found_match_degree= 0; + Item_field *cur_field; + int cur_match_degree= 0; + + if (find_item->type() == Item::FIELD_ITEM || + find_item->type() == Item::REF_ITEM) + { + db_name= ((Item_ident*) find_item)->db_name; + table_name= ((Item_ident*) find_item)->table_name; + field_name= ((Item_ident*) find_item)->field_name; + } + else + return NULL; + + DBUG_ASSERT(field_name); + + for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next) + { + if ((*(cur_group->item))->type() == Item::FIELD_ITEM) + { + cur_field= (Item_field*) *cur_group->item; + cur_match_degree= 0; + + DBUG_ASSERT(cur_field->field_name); + + if (!my_strcasecmp(system_charset_info, + cur_field->field_name, field_name)) + ++cur_match_degree; + else + continue; + + if (cur_field->table_name && table_name && + !strcmp(cur_field->table_name, table_name)) + { /* If field_name is qualified by a table name. */ + ++cur_match_degree; + if (cur_field->db_name && db_name && + !strcmp(cur_field->db_name, db_name)) + /* If field_name is also qualified by a database name. */ + ++cur_match_degree; + } + + if (cur_match_degree > found_match_degree) + { + found_match_degree= cur_match_degree; + found_group= cur_group; + } + } + } + if (found_group) + return found_group->item; + else + return NULL; +} + + +/* + Resolve the name of a column reference. + + SYNOPSIS + Item_ref::fix_fields() + thd [in] Current thread + tables [in] The tables in the FROM clause + reference [in/out] View column if this item was resolved to a view column + + DESCRIPTION + The method resolves the column reference represented by this as an Item + present in either of: GROUP BY clause, SELECT clause, outer queries. It is + used for columns in the HAVING clause which are not under aggregate + functions. + + NOTES + The name resolution algorithm used is: + resolve_extended([T_j].col_ref_i) + { + Search for a column named col_ref_i [in table T_j] + in the GROUP BY clause of Q. + + Search for a column or derived column named col_ref_i [in table T_j] + in the SELECT list of Q. + + if found different columns with the same name in GROUP BY and SELECT + issue an error. + + // Lookup in outer queries. + if such a column is NOT found AND there are outer queries + { + for each outer query Q_k beginning from the inner-most one + { + search for a column or derived column named col_ref_i + [in table T_j] in the SELECT list of Q_k; + if such a column is not found + { + search for a column or derived column named col_ref_i + [in table T_j] in the FROM clause of Q_k; + } + } + } + } + This procedure treats GROUP BY and SELECT as one namespace for column + references in HAVING. + + RETURN + TRUE if error + FALSE on success +*/ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { DBUG_ASSERT(fixed == 0); uint counter; + SELECT_LEX *current_sel= thd->lex->current_select; + List *search_namespace= current_sel->get_item_list(); + bool is_having_field= current_sel->having_fix_field; + Item **group_by_ref= NULL; + if (!ref) { TABLE_LIST *table_list; bool upward_lookup= 0; - SELECT_LEX_UNIT *prev_unit= thd->lex->current_select->master_unit(); - SELECT_LEX *sl= prev_unit->outer_select(); + SELECT_LEX_UNIT *prev_unit= current_sel->master_unit(); + SELECT_LEX *outer_sel= prev_unit->outer_select(); + /* - Finding only in current select will be performed for selects that have - not outer one and for derived tables (which not support using outer - fields for now) + Search for a column or derived column named as 'this' in the SELECT + clause of current_select. */ - if ((ref= find_item_in_list(this, - *(thd->lex->current_select->get_item_list()), - &counter, - ((sl && - thd->lex->current_select->master_unit()-> - first_select()->linkage != - DERIVED_TABLE_TYPE) ? - REPORT_EXCEPT_NOT_FOUND : - REPORT_ALL_ERRORS))) == - (Item **)not_found_item) + if (!(ref= find_item_in_list(this, *search_namespace, &counter, + REPORT_EXCEPT_NOT_FOUND))) + return TRUE; /* Some error occurred. */ + + /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ + if (is_having_field && !this->with_sum_func) + { + group_by_ref= find_field_in_group_list(this, (ORDER*) + current_sel->group_list.first); + /* Check if the fields found in SELECT and GROUP BY are the same field. */ + if (group_by_ref && ref != (Item **) not_found_item && + !((*group_by_ref)->eq(*ref, 0))) + { + my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), + MYF(0), this->full_name(), current_thd->where); + return TRUE; + } + } + + + /* + If we didn't find such a column in the current query, and if there is an + outer select, and this is not a derived table (which do not support the + use of outer fields for now), search the outer select(s) for a column + named as 'this'. + */ + if (!group_by_ref && (ref == (Item **) not_found_item) && outer_sel && + (current_sel->master_unit()->first_select()->linkage != + DERIVED_TABLE_TYPE)) { - upward_lookup= 1; - Field *tmp= (Field*) not_found_field; /* - We can't find table field in table list of current select, - consequently we have to find it in outer subselect(s). - We can't join lists of outer & current select, because of scope - of view rules. For example if both tables (outer & current) have - field 'field' it is not mistake to refer to this field without - mention of table name, but if we join tables in one list it will - cause error ER_NON_UNIQ_ERROR in find_item_in_list. + We can't join the columns of the outer & current selects, because of + scope of view rules. For example if both tables (outer & current) have + field 'field' it is not a mistake to refer to this field without + qualifying it with a table name, but if we join tables in one list it + will cause error ER_NON_UNIQ_ERROR in find_item_in_list. */ + upward_lookup= 1; + Field *tmp= (Field*) not_found_field; SELECT_LEX *last=0; - for ( ; sl ; sl= (prev_unit= sl->master_unit())->outer_select()) + + for ( ; outer_sel ; + outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) { - last= sl; + last= outer_sel; Item_subselect *prev_subselect_item= prev_unit->item; - if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && - (ref= find_item_in_list(this, sl->item_list, + + /* Search in the SELECT list of the current outer sub-select. */ + if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE && + (ref= find_item_in_list(this, outer_sel->item_list, &counter, REPORT_EXCEPT_NOT_FOUND)) != (Item **)not_found_item) @@ -2321,21 +2474,24 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } break; } - table_list= sl->get_table_list(); - if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) + + /* Search in the tables in the FROM clause of the outer select. */ + table_list= outer_sel->get_table_list(); + if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) { - // it is primary INSERT st_select_lex => skip first table resolving + /* It is primary INSERT st_select_lex => skip the first table. */ table_list= table_list->next_local; } enum_parsing_place place= prev_subselect_item->parsing_place; /* - Check table fields only if subquery used somewhere out of HAVING - or SELECT list or outer SELECT do not use groupping (i.e. tables - are accessable) + Check table fields only if the subquery is used somewhere out of + HAVING or SELECT list, or outer SELECT does not use grouping + (i.e. tables are accessible) */ if (((place != IN_HAVING && place != SELECT_LIST) || - (sl->with_sum_func == 0 && sl->group_list.elements == 0)) && + (outer_sel->with_sum_func == 0 && + outer_sel->group_list.elements == 0)) && (tmp= find_field_in_tables(thd, this, table_list, reference, 0, 1)) != not_found_field) @@ -2362,53 +2518,50 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; prev_subselect_item->const_item_cache= 0; - if (sl->master_unit()->first_select()->linkage == + if (outer_sel->master_unit()->first_select()->linkage == DERIVED_TABLE_TYPE) - break; // do not look over derived table + break; /* Do not consider derived tables. */ } if (!ref) - return 1; + return TRUE; else if (!tmp) - return -1; + return TRUE; else if (ref == (Item **)not_found_item && tmp == not_found_field) { if (upward_lookup) { - // We can't say exactly what absend (table or field) + /* We can't say exactly what was absent (a table or a field). */ my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), full_name(), thd->where); } else { // Call to report error - find_item_in_list(this, - *(thd->lex->current_select->get_item_list()), - &counter, + find_item_in_list(this, *search_namespace, &counter, REPORT_ALL_ERRORS); } ref= 0; - return 1; + return TRUE; } else if (tmp != not_found_field) { - ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item + ref= 0; // To prevent "delete *ref;" on ~Item_ref() of this item if (tmp != view_ref_found) { Item_field* fld; if (!((*reference)= fld= new Item_field(tmp))) - return 1; - mark_as_dependent(thd, last, thd->lex->current_select, fld); + return TRUE; + mark_as_dependent(thd, last, current_sel, fld); register_item_tree_changing(reference); - return 0; + return FALSE; } /* We can leave expression substituted from view for next PS/SP - rexecution (i.e. do not register this substitution for reverting - on cleupup() (register_item_tree_changing())), because this - subtree will be fix_field'ed during - setup_tables()->setup_ancestor() (i.e. before all other - expressions of query, and references on tables which do not + re-execution (i.e. do not register this substitution for reverting on + cleanup() (register_item_tree_changing())), because this subtree will + be fix_field'ed during setup_tables()->setup_ancestor() (i.e. before + all other expressions of query, and references on tables which do not present in query will not make problems. Also we suppose that view can't be changed during PS/SP life. @@ -2420,24 +2573,34 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, "forward reference in item list"); - return -1; + return TRUE; } - mark_as_dependent(thd, last, thd->lex->current_select, + mark_as_dependent(thd, last, current_sel, this); ref= last->ref_pointer_array + counter; } } - else if (!ref) - return 1; + else if (!group_by_ref && ref == (Item **) not_found_item) + { + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + this->full_name(), current_thd->where); + return TRUE; + } else { + if (ref != (Item **) not_found_item) + ref= current_sel->ref_pointer_array + counter; + else if (group_by_ref) + ref= group_by_ref; + else + DBUG_ASSERT(FALSE); + if (!(*ref)->fixed) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, "forward reference in item list"); - return -1; + return TRUE; } - ref= thd->lex->current_select->ref_pointer_array + counter; } } @@ -2450,15 +2613,14 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) */ if (((*ref)->with_sum_func && name && (depended_from || - !(thd->lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && - thd->lex->current_select->having_fix_field))) || + !(current_sel->linkage != GLOBAL_OPTIONS_TYPE && is_having_field))) || !(*ref)->fixed) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, ((*ref)->with_sum_func? "reference on group function": "forward reference in item list")); - return 1; + return TRUE; } max_length= (*ref)->max_length; maybe_null= (*ref)->maybe_null; @@ -2468,8 +2630,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) fixed= 1; if (ref && (*ref)->check_cols(1)) - return 1; - return 0; + return TRUE; + return FALSE; } -- cgit v1.2.1 From 3ff74fe4a07b407166fb1b35ba48db0949e7d175 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 1 Nov 2004 12:08:44 +0200 Subject: mysqld.cc: Describe innodb_max_purge_lag Improve description of innodb_table_locks sql/mysqld.cc: Describe innodb_max_purge_lag Improve description of innodb_table_locks --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d36b441ac9a..768acd77c27 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3702,12 +3702,12 @@ struct my_option my_long_options[] = "Percentage of dirty pages allowed in bufferpool", (gptr*) &srv_max_buf_pool_modified_pct, (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, {"innodb_max_purge_lag", OPT_INNODB_MAX_PURGE_LAG, - "", + "Desired maximum length of the purge queue (0 = no limit)", (gptr*) &srv_max_purge_lag, (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, {"innodb_table_locks", OPT_INNODB_TABLE_LOCKS, - "If Innodb should enforce LOCK TABLE", + "Enable InnoDB locking in LOCK TABLES", (gptr*) &global_system_variables.innodb_table_locks, (gptr*) &global_system_variables.innodb_table_locks, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, -- cgit v1.2.1 From 9c06c80dff5744ac0b1d214404c9d16f752e41bb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2004 13:21:11 +0200 Subject: ha_innodb.cc: Backport Jan's fix of the LOAD DATA INFILE REPLACE duplicate key error bug (Bug #5835) to 4.0 sql/ha_innodb.cc: Backport Jan's fix of the LOAD DATA INFILE REPLACE duplicate key error bug (Bug #5835) to 4.0 --- sql/ha_innodb.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e747ff3210c..d57a9f73c91 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2285,7 +2285,9 @@ ha_innobase::write_row( if (error == DB_DUPLICATE_KEY && (user_thd->lex.sql_command == SQLCOM_REPLACE || user_thd->lex.sql_command - == SQLCOM_REPLACE_SELECT)) { + == SQLCOM_REPLACE_SELECT + || (user_thd->lex.sql_command == SQLCOM_LOAD + && user_thd->lex.duplicates == DUP_REPLACE))) { skip_auto_inc_decr= TRUE; } -- cgit v1.2.1 From 048d731a3112e5745038f422da3f1a5c1fadde81 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2004 18:23:15 +0200 Subject: WL#1972 "Evaluate HAVING before SELECT select-list" - Changed name resolution for GROUP BY so that derived columns do not shadow table columns from the FROM clause. As a result GROUP BY now is handled as a true ANSI extentsion. - Issue a warning when HAVING is resolved into ambiguous columns, and prefer the columns from the GROUP BY clause over SELECT columns. mysql-test/r/having.result: Correct result for updated GROUP BY name resolution. sql/item.cc: - prefer GROUP columns, but if none is found use SELECT list - issue a waring when a field may be resolved ambiguously - more/fixed comments sql/mysql_priv.h: More flexible find_field_in_tables(). sql/sp.cc: More flexible find_field_in_tables(). sql/sql_base.cc: More flexible find_field_in_tables(). sql/sql_help.cc: More flexible find_field_in_tables(). sql/sql_select.cc: - name resolution of GROUP/ORDER BY column references is differentiated: - GROUP BY is resolved in SELECT and FROM clauses - ORDER BY is resolved only in SELECT (as before) - more informative variable names - more comments --- sql/item.cc | 69 +++++++++++++++++++++++---------------- sql/mysql_priv.h | 9 ++++-- sql/sp.cc | 2 +- sql/sql_base.cc | 64 ++++++++++++++++++++++-------------- sql/sql_help.cc | 2 +- sql/sql_select.cc | 97 ++++++++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 168 insertions(+), 75 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index b500d84ec4a..738814bc353 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1397,7 +1397,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { bool upward_lookup= 0; Field *tmp= (Field *)not_found_field; - if ((tmp= find_field_in_tables(thd, this, tables, ref, 0, + if ((tmp= find_field_in_tables(thd, this, tables, ref, + IGNORE_EXCEPT_NON_UNIQUE, !any_privileges)) == not_found_field) { @@ -1449,7 +1450,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) (sl->with_sum_func == 0 && sl->group_list.elements == 0)) && (tmp= find_field_in_tables(thd, this, table_list, ref, - 0, 1)) != not_found_field) + IGNORE_EXCEPT_NON_UNIQUE, 1)) != + not_found_field) { if (tmp) { @@ -1505,7 +1507,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) else { // Call to report error - find_field_in_tables(thd, this, tables, ref, 1, 1); + find_field_in_tables(thd, this, tables, ref, REPORT_ALL_ERRORS, 1); } return -1; } @@ -2347,31 +2349,39 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) SYNOPSIS Item_ref::fix_fields() - thd [in] Current thread - tables [in] The tables in the FROM clause - reference [in/out] View column if this item was resolved to a view column + thd [in] current thread + tables [in] the tables in the FROM clause + reference [in/out] view column if this item was resolved to a view column DESCRIPTION - The method resolves the column reference represented by this as an Item - present in either of: GROUP BY clause, SELECT clause, outer queries. It is + The method resolves the column reference represented by 'this' as a column + present in one of: GROUP BY clause, SELECT clause, outer queries. It is used for columns in the HAVING clause which are not under aggregate functions. NOTES + The general idea behind the name resolution algorithm is that it searches + both the SELECT and GROUP BY clauses, and in case of a name conflict + prefers GROUP BY column names over SELECT names. We extend ANSI SQL in that + when no GROUP BY column is found, then a HAVING name is resolved as a + possibly derived SELECT column. + The name resolution algorithm used is: + resolve_extended([T_j].col_ref_i) { - Search for a column named col_ref_i [in table T_j] - in the GROUP BY clause of Q. - Search for a column or derived column named col_ref_i [in table T_j] in the SELECT list of Q. - if found different columns with the same name in GROUP BY and SELECT - issue an error. + Search for a column named col_ref_i [in table T_j] + in the GROUP BY clause of Q. + + If found different columns with the same name in GROUP BY and SELECT + issue a warning and return the GROUP BY column, + otherwise return the found SELECT column. - // Lookup in outer queries. - if such a column is NOT found AND there are outer queries + if such a column is NOT found AND // Lookup in outer queries. + there are outer queries { for each outer query Q_k beginning from the inner-most one { @@ -2385,8 +2395,9 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) } } } - This procedure treats GROUP BY and SELECT as one namespace for column - references in HAVING. + + This procedure treats GROUP BY and SELECT clauses as one namespace for + column references in HAVING. RETURN TRUE if error @@ -2398,9 +2409,10 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) DBUG_ASSERT(fixed == 0); uint counter; SELECT_LEX *current_sel= thd->lex->current_select; - List *search_namespace= current_sel->get_item_list(); + List *select_fields= current_sel->get_item_list(); bool is_having_field= current_sel->having_fix_field; Item **group_by_ref= NULL; + bool ambiguous_fields= FALSE; if (!ref) { @@ -2413,7 +2425,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) Search for a column or derived column named as 'this' in the SELECT clause of current_select. */ - if (!(ref= find_item_in_list(this, *search_namespace, &counter, + if (!(ref= find_item_in_list(this, *select_fields, &counter, REPORT_EXCEPT_NOT_FOUND))) return TRUE; /* Some error occurred. */ @@ -2422,20 +2434,22 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { group_by_ref= find_field_in_group_list(this, (ORDER*) current_sel->group_list.first); + /* Check if the fields found in SELECT and GROUP BY are the same field. */ if (group_by_ref && ref != (Item **) not_found_item && !((*group_by_ref)->eq(*ref, 0))) { - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - MYF(0), this->full_name(), current_thd->where); - return TRUE; + ambiguous_fields= TRUE; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), + this->full_name(), current_thd->where); + } } - /* If we didn't find such a column in the current query, and if there is an - outer select, and this is not a derived table (which do not support the + outer select, and it is not a derived table (which do not support the use of outer fields for now), search the outer select(s) for a column named as 'this'. */ @@ -2494,7 +2508,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) outer_sel->group_list.elements == 0)) && (tmp= find_field_in_tables(thd, this, table_list, reference, - 0, 1)) != not_found_field) + IGNORE_EXCEPT_NON_UNIQUE, TRUE)) != + not_found_field) { if (tmp) { @@ -2538,7 +2553,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) else { // Call to report error - find_item_in_list(this, *search_namespace, &counter, + find_item_in_list(this, *select_fields, &counter, REPORT_ALL_ERRORS); } ref= 0; @@ -2588,7 +2603,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } else { - if (ref != (Item **) not_found_item) + if (ref != (Item **) not_found_item && !ambiguous_fields) ref= current_sel->ref_pointer_array + counter; else if (group_by_ref) ref= group_by_ref; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d8916149b77..8c27e0130a1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -650,8 +650,13 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var, rw_lock_t *var_mutex); extern const Field *not_found_field; extern const Field *view_ref_found; + +enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, + IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE, + IGNORE_EXCEPT_NON_UNIQUE}; Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, - Item **ref, bool report_error, + Item **ref, + find_item_error_report_type report_error, bool check_privileges); Field * find_field_in_table(THD *thd, TABLE_LIST *table_list, @@ -765,8 +770,6 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find); SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, int *error, bool allow_null_cond= false); -enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, - IGNORE_ERRORS}; extern const Item **not_found_item; Item ** find_item_in_list(Item *item, List &items, uint *counter, find_item_error_report_type report_error); diff --git a/sql/sp.cc b/sql/sp.cc index e444a412760..323c1acd525 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -615,7 +615,7 @@ db_show_routine_status(THD *thd, int type, const char *wild) Item_field *field= new Item_field("mysql", "proc", used_field->field_name); if (!(used_field->field= find_field_in_tables(thd, field, &tables, - 0, TRUE, 1))) + 0, REPORT_ALL_ERRORS, 1))) { res= SP_INTERNAL_ERROR; goto err_case1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4f273fbd0c4..a8a44205b64 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2173,25 +2173,33 @@ Field *find_field_in_real_table(THD *thd, TABLE *table, find_field_in_tables() thd Pointer to current thread structure item Field item that should be found - tables Tables for scanning - ref if view field is found, pointer to view item will - be returned via this parameter - report_error If FALSE then do not report error if item not found - and return not_found_field + tables Tables to be searched for item + ref If 'item' is resolved to a view field, ref is set to + point to the found view field + report_error Degree of error reporting: + - IGNORE_ERRORS then do not report any error + - IGNORE_EXCEPT_NON_UNIQUE report only non-unique + fields, suppress all other errors + - REPORT_EXCEPT_NON_UNIQUE report all other errors + except when non-unique fields were found + - REPORT_ALL_ERRORS check_privileges need to check privileges RETURN VALUES - 0 Field is not found or field is not unique- error - message is reported - not_found_field Function was called with report_error == FALSE and - field was not found. no error message reported. - view_ref_found view field is found, item passed through ref parameter - found field + 0 No field was found, or the found field is not unique, or + there are no sufficient access priviligaes for the + found field, or the field is qualified with non-existing + table. + not_found_field The function was called with report_error == + (IGNORE_ERRORS || IGNORE_EXCEPT_NON_UNIQUE) and a + field was not found. + view_ref_found View field is found, item passed through ref parameter + found field If a item was resolved to some field */ Field * find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, - Item **ref, bool report_error, + Item **ref, find_item_error_report_type report_error, bool check_privileges) { Field *found=0; @@ -2268,8 +2276,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, return find; if (found) { - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - item->full_name(),thd->where); + if (report_error == REPORT_ALL_ERRORS || + report_error == IGNORE_EXCEPT_NON_UNIQUE) + my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), + item->full_name(),thd->where); return (Field*) 0; } found=find; @@ -2278,7 +2288,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, } if (found) return found; - if (!found_table && report_error) + if (!found_table && (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE)) { char buff[NAME_LEN*2+1]; if (db && db[0]) @@ -2286,28 +2297,30 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS); table_name=buff; } - if (report_error) - { + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), table_name, thd->where); - } else return (Field*) not_found_field; } else - if (report_error) + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), item->full_name(),thd->where); else return (Field*) not_found_field; return (Field*) 0; } + bool allow_rowid= tables && !tables->next_local; // Only one table for (; tables ; tables= tables->next_local) { if (!tables->table) { - if (report_error) + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), item->full_name(),thd->where); return (Field*) not_found_field; @@ -2332,8 +2345,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, { if (!thd->where) // Returns first found break; - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - name,thd->where); + if (report_error == REPORT_ALL_ERRORS || + report_error == IGNORE_EXCEPT_NON_UNIQUE) + my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), + name,thd->where); return (Field*) 0; } found=field; @@ -2341,7 +2356,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, } if (found) return found; - if (report_error) + if (report_error == REPORT_ALL_ERRORS || + report_error == REPORT_EXCEPT_NON_UNIQUE) my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), item->full_name(), thd->where); else @@ -2377,7 +2393,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, found field */ -// Special Item pointer for find_item_in_list returning +/* Special Item pointer to serve as a return value from find_item_in_list(). */ const Item **not_found_item= (const Item**) 0x1; diff --git a/sql/sql_help.cc b/sql/sql_help.cc index cba74c93a6a..62ee708b695 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -88,7 +88,7 @@ static bool init_fields(THD *thd, TABLE_LIST *tables, Item_field *field= new Item_field("mysql", find_fields->table_name, find_fields->field_name); if (!(find_fields->field= find_field_in_tables(thd, field, tables, - 0, TRUE, 1))) + 0, REPORT_ALL_ERRORS, 1))) DBUG_RETURN(1); } DBUG_RETURN(0); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9ba191a3f3a..99d076bd335 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11115,24 +11115,53 @@ cp_buffer_from_ref(TABLE_REF *ref) *****************************************************************************/ /* - Find order/group item in requested columns and change the item to point at - it. If item doesn't exists, add it first in the field list - Return 0 if ok. + Resolve an ORDER BY or GROUP BY column reference. + + SYNOPSIS + find_order_in_list() + thd [in] Pointer to current thread structure + ref_pointer_array [in/out] All select, group and order by fields + tables [in] List of tables to search in (usually FROM clause) + order [in] Column reference to be resolved + fields [in] List of fields to search in (usually SELECT list) + all_fields [in/out] All select, group and order by fields + is_group_field [in] True if order is a GROUP field, false if + ORDER by field + + DESCRIPTION + Given a column reference (represented by 'order') from a GROUP BY or ORDER + BY clause, find the actual column it represents. If the column being + resolved is from the GROUP BY clause, the procedure searches the SELECT + list 'fields' and the columns in the FROM list 'tables'. If 'order' is from + the ORDER BY clause, only the SELECT list is being searched. + + If 'order' is resolved to an Item, then order->item is set to the found + Item. If there is no item for the found column (that is, it was resolved + into a table field), order->item is 'fixed' and is added to all_fields and + ref_pointer_array. + + RETURN + 0 if ok + 1 if error occurred */ static int -find_order_in_list(THD *thd, Item **ref_pointer_array, - TABLE_LIST *tables,ORDER *order, List &fields, - List &all_fields) +find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, + ORDER *order, List &fields, List &all_fields, + bool is_group_field) { - Item *itemptr=*order->item; - if (itemptr->type() == Item::INT_ITEM) + Item *order_item=*order->item; /* The item from the GROUP/ORDER caluse. */ + Item::Type order_item_type; + Item **select_item; /* The corresponding item from the SELECT clause. */ + Field *from_field; /* The corresponding field from the FROM clause. */ + + if (order_item->type() == Item::INT_ITEM) { /* Order by position */ - uint count= (uint) itemptr->val_int(); + uint count= (uint) order_item->val_int(); if (!count || count > fields.elements) { my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), - MYF(0),itemptr->full_name(), + MYF(0),order_item->full_name(), thd->where); return 1; } @@ -11142,17 +11171,47 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, order->counter_used= 1; return 0; } + /* Lookup the current GROUP/ORDER field in the SELECT clause. */ uint counter; - Item **item= find_item_in_list(itemptr, fields, &counter, + select_item= find_item_in_list(order_item, fields, &counter, REPORT_EXCEPT_NOT_FOUND); - if (!item) - return 1; + if (!select_item) + return 1; /* Some error occured. */ + - if (item != (Item **)not_found_item) + /* Check whether the resolved field is not ambiguos. */ + if (select_item != not_found_item) { - order->item= ref_pointer_array + counter; - order->in_field_list=1; - return 0; + /* Lookup the current GROUP field in the FROM clause. */ + order_item_type= order_item->type(); + if (is_group_field && + order_item_type == Item::FIELD_ITEM || order_item_type == Item::REF_ITEM) + { + Item **view_ref= NULL; + from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables, + view_ref, IGNORE_ERRORS, TRUE); + if(!from_field) + from_field= (Field*) not_found_field; + } + else + from_field= (Field*) not_found_field; + + if (from_field == not_found_field || + from_field && from_field != view_ref_found && + (*select_item)->type() == Item::FIELD_ITEM && + ((Item_field*) (*select_item))->field->eq(from_field)) + /* + If there is no such field in the FROM clause, or it is the same field as + the one found in the SELECT clause, then use the Item created for the + SELECT field. As a result if there was a derived field that 'shadowed' + a table field with the same name, the table field will be chosen over + the derived field. + */ + { + order->item= ref_pointer_array + counter; + order->in_field_list=1; + return 0; + } } order->in_field_list=0; @@ -11187,7 +11246,7 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, for (; order; order=order->next) { if (find_order_in_list(thd, ref_pointer_array, tables, order, fields, - all_fields)) + all_fields, FALSE)) return 1; } return 0; @@ -11239,7 +11298,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, for (; order; order=order->next) { if (find_order_in_list(thd, ref_pointer_array, tables, order, fields, - all_fields)) + all_fields, TRUE)) return 1; (*order->item)->marker=1; /* Mark found */ if ((*order->item)->with_sum_func) -- cgit v1.2.1 From c7bfc95936d8b0a1395c201da7956f4c4e8f4927 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Nov 2004 20:11:00 +0200 Subject: fixed spelling --- sql/sql_base.cc | 11 ++++++----- sql/sql_select.cc | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a8a44205b64..9f9b9b4ed63 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2187,7 +2187,7 @@ Field *find_field_in_real_table(THD *thd, TABLE *table, RETURN VALUES 0 No field was found, or the found field is not unique, or - there are no sufficient access priviligaes for the + there are no sufficient access priviliges for the found field, or the field is qualified with non-existing table. not_found_field The function was called with report_error == @@ -2217,8 +2217,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, TABLE_LIST *tables is not changed during query execution (which is true for all queries except RENAME but luckily RENAME doesn't use fields...) so we can rely on reusing pointer to its member. - With this optimisation we also miss case when addition of one more - field makes some prepared query ambiguous and so erronous, but we + With this optimization we also miss case when addition of one more + field makes some prepared query ambiguous and so erroneous, but we accept this trade off. */ found= find_field_in_real_table(thd, item->cached_table->table, @@ -2239,7 +2239,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, if (db && lower_case_table_names) { /* - convert database to lower case for comparision. + convert database to lower case for comparison. We can't do this in Item_field as this would change the 'name' of the item which may be used in the select list */ @@ -2779,7 +2779,8 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, any_privileges 0 If we should ensure that we have SELECT privileges for all columns 1 If any privilege is ok - allocate_view_names if true view names will be copied to current Item_arena memory (made for SP/PS) + allocate_view_names if true view names will be copied to current Item_arena + memory (made for SP/PS) RETURN 0 ok 'it' is updated to point at last inserted diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 99d076bd335..178d36faa2a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11141,7 +11141,7 @@ cp_buffer_from_ref(TABLE_REF *ref) ref_pointer_array. RETURN - 0 if ok + 0 if OK 1 if error occurred */ -- cgit v1.2.1 From d259ba4006a683e953486191d2851ee6c63f66b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Nov 2004 17:59:03 +0000 Subject: Fix for bug #6387 "Queried timestamp values do not match the inserted value if server runs in time zone with leap seconds". Now in my_gmt_sec() function we take into account difference between our target and estimation in seconds part. mysql-test/Makefile.am: Added mysql-test/std_data/Moscow_leap reuired by new timezone3.test to source distribution. sql/time.cc: my_gmt_sec(): When comparing our target broken-down datetime t value and proper representation of our estimation *l_time we should take into account that they could differ in second part if we have time zone leap seconds. Also added comments about some assumptions used in this function. --- sql/time.cc | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/time.cc b/sql/time.cc index 0363d764100..38670db054f 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -81,6 +81,10 @@ long my_gmt_sec(TIME *t, long *my_timezone) I couldn't come up with a better way to get a repeatable result :( We can't use mktime() as it's buggy on many platforms and not thread safe. + + Note: this code assumes that our time_t estimation is not too far away + from real value (we assume that localtime_r(tmp) will return something + within 24 hrs from t) which is probably true for all current time zones. */ tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) - (long) days_at_timestart)*86400L + (long) t->hour*3600L + @@ -93,7 +97,8 @@ long my_gmt_sec(TIME *t, long *my_timezone) for (loop=0; loop < 2 && (t->hour != (uint) l_time->tm_hour || - t->minute != (uint) l_time->tm_min); + t->minute != (uint) l_time->tm_min || + t->second != (uint) l_time->tm_sec); loop++) { /* One check should be enough ? */ /* Get difference in days */ @@ -103,15 +108,22 @@ long my_gmt_sec(TIME *t, long *my_timezone) else if (days > 1) days= -1; diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) + - (long) (60*((int) t->minute - (int) l_time->tm_min))); + (long) (60*((int) t->minute - (int) l_time->tm_min)) + + (long) ((int) t->second - (int) l_time->tm_sec)); current_timezone+= diff+3600; // Compensate for -3600 above tmp+= (time_t) diff; localtime_r(&tmp,&tm_tmp); l_time=&tm_tmp; } /* - Fix that if we are in the not existing daylight saving time hour - we move the start of the next real hour + Fix that if we are in the non existing daylight saving time hour + we move the start of the next real hour. + + This code doesn't handle such exotical thing as time-gaps whose length + is more than one hour or non-integer (latter can theoretically happen + if one of seconds will be removed due leap correction, or because of + general time correction like it happened for Africa/Monrovia time zone + in year 1972). */ if (loop == 2 && t->hour != (uint) l_time->tm_hour) { @@ -121,7 +133,8 @@ long my_gmt_sec(TIME *t, long *my_timezone) else if (days > 1) days= -1; diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour))+ - (long) (60*((int) t->minute - (int) l_time->tm_min))); + (long) (60*((int) t->minute - (int) l_time->tm_min)) + + (long) ((int) t->second - (int) l_time->tm_sec)); if (diff == 3600) tmp+=3600 - t->minute*60 - t->second; // Move to next hour else if (diff == -3600) -- cgit v1.2.1 From e30bd1e48d8ef68a92dd8443611b1e3d8e356c7a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Nov 2004 19:19:23 +0100 Subject: Fix for BUG##5714 "Insert into MyISAM table and select ... for update]": the fact that the transaction log is empty does not mean we're not in a transaction (it could be BEGIN; SELECT * FOR UPDATE FROM ibtable: then we don't want to commit now, even if the statement is a MyISAM update). With a testcase. mysql-test/r/mix_innodb_myisam_binlog.result: result update mysql-test/t/mix_innodb_myisam_binlog.test: test update for a new bug sql/log.cc: The fact that the transaction log is empty does not mean we're not in a transaction (it could be BEGIN; SELECT * FOR UPDATE: then we don't want to commit now). --- sql/log.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index fee77b38f21..aa5d9d8753b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1254,7 +1254,8 @@ bool MYSQL_LOG::write(Log_event* event_info) if (flush_io_cache(file)) goto err; - if (opt_using_transactions && !my_b_tell(&thd->transaction.trans_log)) + if (opt_using_transactions && + !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { /* LOAD DATA INFILE in AUTOCOMMIT=1 mode writes to the binlog -- cgit v1.2.1 From 47a96b3195b3f893207c0ba5c7f3600e5d95cf56 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Nov 2004 15:48:44 +0200 Subject: WL#1972 "Evaluate HAVING before SELECT" - more tests, post-review changes, bug-fixes, simplifications, and improved comments mysql-test/r/having.result: - added tests for subqueries with HAVING - added tests for few other discovered bugs - renamed tables to the more standard t1,t2,.. mysql-test/t/having.test: - added tests for subqueries with HAVING - added tests for few other discovered bugs - renamed tables to the more standard t1,t2,.. sql/item.cc: - Extended the name resolution to support nested HAVING clauses in nested sub-queries - Factored out the code that resolves a column ref against a single query - Fixed several logical bugs - Removed unused variables - More/better comments sql/sql_base.cc: Corrected function spec. --- sql/item.cc | 468 +++++++++++++++++++++++++++++++------------------------- sql/sql_base.cc | 7 +- 2 files changed, 262 insertions(+), 213 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 738814bc353..8b611f0ddb5 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2320,14 +2320,22 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) else continue; - if (cur_field->table_name && table_name && - !strcmp(cur_field->table_name, table_name)) - { /* If field_name is qualified by a table name. */ + if (cur_field->table_name && table_name) + { + /* If field_name is qualified by a table name. */ + if (strcmp(cur_field->table_name, table_name)) + /* Same field names, different tables. */ + return NULL; + ++cur_match_degree; - if (cur_field->db_name && db_name && - !strcmp(cur_field->db_name, db_name)) + if (cur_field->db_name && db_name) + { /* If field_name is also qualified by a database name. */ + if (strcmp(cur_field->db_name, db_name)) + /* Same field names, different databases. */ + return NULL; ++cur_match_degree; + } } if (cur_match_degree > found_match_degree) @@ -2335,8 +2343,21 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) found_match_degree= cur_match_degree; found_group= cur_group; } + else if (found_group && (cur_match_degree == found_match_degree) && + ! (*(found_group->item))->eq(cur_field, 0)) + { + /* + If the current resolve candidate matches equally well as the current + best match, they must reference the same column, otherwise the field + is ambiguous. + */ + my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), + MYF(0), find_item->full_name(), current_thd->where); + return NULL; + } } } + if (found_group) return found_group->item; else @@ -2344,6 +2365,97 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) } +/* + Resolve a column reference in a sub-select. + + SYNOPSIS + resolve_ref_in_select_and_group() + thd current thread + ref column reference being resolved + select the sub-select that ref is resolved against + + DESCRIPTION + Resolve a column reference (usually inside a HAVING clause) against the + SELECT and GROUP BY clauses of the query described by 'select'. The name + resolution algorithm searches both the SELECT and GROUP BY clauses, and in + case of a name conflict prefers GROUP BY column names over SELECT names. If + both clauses contain different fields with the same names, a warning is + issued that name of 'ref' is ambiguous. We extend ANSI SQL in that when no + GROUP BY column is found, then a HAVING name is resolved as a possibly + derived SELECT column. + + NOTES + The resolution procedure is: + - Search for a column or derived column named col_ref_i [in table T_j] + in the SELECT clause of Q. + - Search for a column named col_ref_i [in table T_j] + in the GROUP BY clause of Q. + - If found different columns with the same name in GROUP BY and SELECT + - issue a warning and return the GROUP BY column, + - otherwise return the found SELECT column. + + + RETURN + NULL - there was an error, and the error was already reported + not_found_item - the item was not resolved, no error was reported + resolved item - if the item was resolved +*/ +static Item** +resolve_ref_in_select_and_group(THD *thd, Item_ref *ref, SELECT_LEX *select) +{ + Item **group_by_ref= NULL; + Item **select_ref= NULL; + ORDER *group_list= (ORDER*) select->group_list.first; + bool ambiguous_fields= FALSE; + uint counter; + + /* + Search for a column or derived column named as 'ref' in the SELECT + clause of the current select. + */ + if (!(select_ref= find_item_in_list(ref, *(select->get_item_list()), &counter, + REPORT_EXCEPT_NOT_FOUND))) + return NULL; /* Some error occurred. */ + + /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ + if (select->having_fix_field && !ref->with_sum_func && group_list) + { + group_by_ref= find_field_in_group_list(ref, group_list); + + /* Check if the fields found in SELECT and GROUP BY are the same field. */ + if (group_by_ref && (select_ref != not_found_item) && + !((*group_by_ref)->eq(*select_ref, 0))) + { + ambiguous_fields= TRUE; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR, + ER(ER_NON_UNIQ_ERROR), ref->full_name(), + current_thd->where); + + } + } + + if (select_ref != not_found_item || group_by_ref) + { + if (select_ref != not_found_item && !ambiguous_fields) + { + if (*select_ref && !(*select_ref)->fixed) + { + my_error(ER_ILLEGAL_REFERENCE, MYF(0), ref->name, + "forward reference in item list"); + return NULL; + } + return (select->ref_pointer_array + counter); + } + else if (group_by_ref) + return group_by_ref; + else + DBUG_ASSERT(FALSE); + } + else + return (Item**) not_found_item; +} + + /* Resolve the name of a column reference. @@ -2356,38 +2468,30 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) DESCRIPTION The method resolves the column reference represented by 'this' as a column present in one of: GROUP BY clause, SELECT clause, outer queries. It is - used for columns in the HAVING clause which are not under aggregate - functions. + used typically for columns in the HAVING clause which are not under + aggregate functions. NOTES - The general idea behind the name resolution algorithm is that it searches - both the SELECT and GROUP BY clauses, and in case of a name conflict - prefers GROUP BY column names over SELECT names. We extend ANSI SQL in that - when no GROUP BY column is found, then a HAVING name is resolved as a - possibly derived SELECT column. - The name resolution algorithm used is: resolve_extended([T_j].col_ref_i) { Search for a column or derived column named col_ref_i [in table T_j] - in the SELECT list of Q. - - Search for a column named col_ref_i [in table T_j] - in the GROUP BY clause of Q. - - If found different columns with the same name in GROUP BY and SELECT - issue a warning and return the GROUP BY column, - otherwise return the found SELECT column. + in the SELECT and GROUP clauses of Q. if such a column is NOT found AND // Lookup in outer queries. there are outer queries { for each outer query Q_k beginning from the inner-most one { - search for a column or derived column named col_ref_i - [in table T_j] in the SELECT list of Q_k; - if such a column is not found + Search for a column or derived column named col_ref_i + [in table T_j] in the SELECT and GROUP clauses of Q_k. + + if such a column is not found AND + - Q_k is not a group query AND + - Q_k is not inside an aggregate function + OR + - Q_(k-1) is not in a HAVING or SELECT clause of Q_k { search for a column or derived column named col_ref_i [in table T_j] in the FROM clause of Q_k; @@ -2407,214 +2511,157 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { DBUG_ASSERT(fixed == 0); - uint counter; SELECT_LEX *current_sel= thd->lex->current_select; - List *select_fields= current_sel->get_item_list(); - bool is_having_field= current_sel->having_fix_field; - Item **group_by_ref= NULL; - bool ambiguous_fields= FALSE; if (!ref) { - TABLE_LIST *table_list; - bool upward_lookup= 0; SELECT_LEX_UNIT *prev_unit= current_sel->master_unit(); SELECT_LEX *outer_sel= prev_unit->outer_select(); + ORDER *group_list= (ORDER*) current_sel->group_list.first; + bool ambiguous_fields= FALSE; + Item **group_by_ref= NULL; - /* - Search for a column or derived column named as 'this' in the SELECT - clause of current_select. - */ - if (!(ref= find_item_in_list(this, *select_fields, &counter, - REPORT_EXCEPT_NOT_FOUND))) - return TRUE; /* Some error occurred. */ - - /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ - if (is_having_field && !this->with_sum_func) - { - group_by_ref= find_field_in_group_list(this, (ORDER*) - current_sel->group_list.first); - - /* Check if the fields found in SELECT and GROUP BY are the same field. */ - if (group_by_ref && ref != (Item **) not_found_item && - !((*group_by_ref)->eq(*ref, 0))) - { - ambiguous_fields= TRUE; - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - this->full_name(), current_thd->where); + if (!(ref= resolve_ref_in_select_and_group(thd, this, current_sel))) + return TRUE; /* Some error occured (e.g. ambigous names). */ - } - } - - /* - If we didn't find such a column in the current query, and if there is an - outer select, and it is not a derived table (which do not support the - use of outer fields for now), search the outer select(s) for a column - named as 'this'. - */ - if (!group_by_ref && (ref == (Item **) not_found_item) && outer_sel && - (current_sel->master_unit()->first_select()->linkage != - DERIVED_TABLE_TYPE)) + if (ref == not_found_item) /* This reference was not resolved. */ { /* - We can't join the columns of the outer & current selects, because of - scope of view rules. For example if both tables (outer & current) have - field 'field' it is not a mistake to refer to this field without - qualifying it with a table name, but if we join tables in one list it - will cause error ER_NON_UNIQ_ERROR in find_item_in_list. + If there is an outer select, and it is not a derived table (which do + not support the use of outer fields for now), try to resolve this + reference in the outer select(s). + + We treat each subselect as a separate namespace, so that different + subselects may contain columns with the same names. The subselects are + searched starting from the innermost. */ - upward_lookup= 1; - Field *tmp= (Field*) not_found_field; - SELECT_LEX *last=0; - - for ( ; outer_sel ; - outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) + if (outer_sel && (current_sel->master_unit()->first_select()->linkage != + DERIVED_TABLE_TYPE)) { - last= outer_sel; - Item_subselect *prev_subselect_item= prev_unit->item; - - /* Search in the SELECT list of the current outer sub-select. */ - if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE && - (ref= find_item_in_list(this, outer_sel->item_list, - &counter, - REPORT_EXCEPT_NOT_FOUND)) != - (Item **)not_found_item) - { - if (*ref && (*ref)->fixed) // Avoid crash in case of error - { - prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); - prev_subselect_item->const_item_cache&= (*ref)->const_item(); - } - break; - } + TABLE_LIST *table_list; + Field *tmp= (Field*) not_found_field; + SELECT_LEX *last= 0; - /* Search in the tables in the FROM clause of the outer select. */ - table_list= outer_sel->get_table_list(); - if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) - { - /* It is primary INSERT st_select_lex => skip the first table. */ - table_list= table_list->next_local; - } - enum_parsing_place place= prev_subselect_item->parsing_place; - /* - Check table fields only if the subquery is used somewhere out of - HAVING or SELECT list, or outer SELECT does not use grouping - (i.e. tables are accessible) - */ - if (((place != IN_HAVING && - place != SELECT_LIST) || - (outer_sel->with_sum_func == 0 && - outer_sel->group_list.elements == 0)) && - (tmp= find_field_in_tables(thd, this, - table_list, reference, - IGNORE_EXCEPT_NON_UNIQUE, TRUE)) != - not_found_field) - { - if (tmp) + for ( ; outer_sel ; + outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) + { + last= outer_sel; + Item_subselect *prev_subselect_item= prev_unit->item; + + /* Search in the SELECT and GROUP lists of the outer select. */ + if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE) { - if (tmp != view_ref_found) + if (!(ref= resolve_ref_in_select_and_group(thd, this, outer_sel))) + return TRUE; /* Some error occured (e.g. ambigous names). */ + if (ref != not_found_item) { - prev_subselect_item->used_tables_cache|= tmp->table->map; - prev_subselect_item->const_item_cache= 0; + DBUG_ASSERT(*ref && (*ref)->fixed); + /* + Avoid crash in case of error. + TODO: what does this comment mean? + */ + prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); + prev_subselect_item->const_item_cache&= (*ref)->const_item(); + break; } - else + } + + /* Search in the tables of the FROM clause of the outer select. */ + table_list= outer_sel->get_table_list(); + if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) + { + /* It is primary INSERT st_select_lex => skip the first table. */ + table_list= table_list->next_local; + } + enum_parsing_place place= prev_subselect_item->parsing_place; + /* + Check table fields only if the subquery is used somewhere out of + HAVING or SELECT list, or outer SELECT does not use grouping + (i.e. tables are accessible). + TODO: + Here we could first find the field anyway, and then test this + condition, so that we can give a better error message - + ER_WRONG_FIELD_WITH_GROUP, instead of the less informative + ER_BAD_FIELD_ERROR which we produce now. + */ + if (((place != IN_HAVING && place != SELECT_LIST) || + (!outer_sel->with_sum_func && + outer_sel->group_list.elements == 0))) + { + if ((tmp= find_field_in_tables(thd, this, table_list, reference, + IGNORE_EXCEPT_NON_UNIQUE, TRUE)) != + not_found_field) { - prev_subselect_item->used_tables_cache|= - (*reference)->used_tables(); - prev_subselect_item->const_item_cache&= - (*reference)->const_item(); + if (tmp != view_ref_found) + { + prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->const_item_cache= 0; + } + else + { + prev_subselect_item->used_tables_cache|= + (*reference)->used_tables(); + prev_subselect_item->const_item_cache&= + (*reference)->const_item(); + } + break; } } - break; - } - // Reference is not found => depend from outer (or just error) - prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; - prev_subselect_item->const_item_cache= 0; + /* Reference is not found => depend on outer (or just error). */ + prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; + prev_subselect_item->const_item_cache= 0; - if (outer_sel->master_unit()->first_select()->linkage == - DERIVED_TABLE_TYPE) - break; /* Do not consider derived tables. */ - } + if (outer_sel->master_unit()->first_select()->linkage == + DERIVED_TABLE_TYPE) + break; /* Do not consider derived tables. */ + } - if (!ref) - return TRUE; - else if (!tmp) - return TRUE; - else if (ref == (Item **)not_found_item && tmp == not_found_field) - { - if (upward_lookup) - { - /* We can't say exactly what was absent (a table or a field). */ - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - full_name(), thd->where); - } - else - { - // Call to report error - find_item_in_list(this, *select_fields, &counter, - REPORT_ALL_ERRORS); - } - ref= 0; - return TRUE; - } - else if (tmp != not_found_field) - { - ref= 0; // To prevent "delete *ref;" on ~Item_ref() of this item - if (tmp != view_ref_found) - { - Item_field* fld; - if (!((*reference)= fld= new Item_field(tmp))) - return TRUE; - mark_as_dependent(thd, last, current_sel, fld); - register_item_tree_changing(reference); - return FALSE; - } - /* - We can leave expression substituted from view for next PS/SP - re-execution (i.e. do not register this substitution for reverting on - cleanup() (register_item_tree_changing())), because this subtree will - be fix_field'ed during setup_tables()->setup_ancestor() (i.e. before - all other expressions of query, and references on tables which do not - present in query will not make problems. - - Also we suppose that view can't be changed during PS/SP life. - */ - } - else - { - if (!(*ref)->fixed) - { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); - return TRUE; - } - mark_as_dependent(thd, last, current_sel, - this); - ref= last->ref_pointer_array + counter; + DBUG_ASSERT(ref); + if (!tmp) + return TRUE; + else if (ref == not_found_item && tmp == not_found_field) + { + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + this->full_name(), current_thd->where); + ref= 0; + return TRUE; + } + else if (tmp != not_found_field) + { + ref= 0; // To prevent "delete *ref;" on ~Item_ref() of this item + if (tmp != view_ref_found) + { + Item_field* fld= new Item_field(tmp); + if (!((*reference)= fld)) + return TRUE; + mark_as_dependent(thd, last, current_sel, fld); + register_item_tree_changing(reference); + return FALSE; + } + /* + We can leave expression substituted from view for next PS/SP + re-execution (i.e. do not register this substitution for reverting + on cleanup() (register_item_tree_changing())), because this subtree + will be fix_field'ed during setup_tables()->setup_ancestor() + (i.e. before all other expressions of query, and references on + tables which do not present in query will not make problems. + + Also we suppose that view can't be changed during PS/SP life. + */ + } + else + { + DBUG_ASSERT(*ref && (*ref)->fixed); + mark_as_dependent(thd, last, current_sel, this); + } } - } - else if (!group_by_ref && ref == (Item **) not_found_item) - { - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - this->full_name(), current_thd->where); - return TRUE; - } - else - { - if (ref != (Item **) not_found_item && !ambiguous_fields) - ref= current_sel->ref_pointer_array + counter; - else if (group_by_ref) - ref= group_by_ref; else - DBUG_ASSERT(FALSE); - - if (!(*ref)->fixed) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); - return TRUE; + /* The current reference cannot be resolved in this query. */ + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + this->full_name(), current_thd->where); + return TRUE; } } } @@ -2625,15 +2672,18 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) with sub-select's / derived tables, while it prevents this check when Item_ref is created in an expression involving summing function, which is to be placed in the user variable. + + TODO: this comment is impossible to understand. */ if (((*ref)->with_sum_func && name && (depended_from || - !(current_sel->linkage != GLOBAL_OPTIONS_TYPE && is_having_field))) || + !(current_sel->linkage != GLOBAL_OPTIONS_TYPE && + current_sel->having_fix_field))) || !(*ref)->fixed) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, ((*ref)->with_sum_func? - "reference on group function": + "reference to group function": "forward reference in item list")); return TRUE; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9f9b9b4ed63..e65cfaccad1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2186,10 +2186,9 @@ Field *find_field_in_real_table(THD *thd, TABLE *table, check_privileges need to check privileges RETURN VALUES - 0 No field was found, or the found field is not unique, or - there are no sufficient access priviliges for the - found field, or the field is qualified with non-existing - table. + 0 If error: the found field is not unique, or there are + no sufficient access priviliges for the found field, + or the field is qualified with non-existing table. not_found_field The function was called with report_error == (IGNORE_ERRORS || IGNORE_EXCEPT_NON_UNIQUE) and a field was not found. -- cgit v1.2.1 From bf14010d517460de1e6fa4b342b93917135c0818 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Nov 2004 13:15:01 +0400 Subject: ctype_ujis.result, ctype_ujis.test, field.cc: Bug#6345 Unexpected behaviour with partial indices sql/field.cc: Bug#6345 Unexpected behaviour with partial indices mysql-test/t/ctype_ujis.test: Bug#6345 Unexpected behaviour with partial indices mysql-test/r/ctype_ujis.result: Bug#6345 Unexpected behaviour with partial indices --- sql/field.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 24bd0c48c92..1111e47bc38 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4401,10 +4401,14 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) (const uchar*) b_ptr, field_length); } - return my_strnncoll(field_charset,(const uchar*) a_ptr, field_length, - (const uchar*) b_ptr, field_length); + uint char_len= field_length/field_charset->mbmaxlen; + uint a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len); + uint b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len); + return my_strnncoll(field_charset,(const uchar*) a_ptr, a_len, + (const uchar*) b_ptr, b_len); } + void Field_string::sort_string(char *to,uint length) { uint tmp=my_strnxfrm(field_charset, -- cgit v1.2.1 From 3b38a854e0fed2edaf6ab848959a2795445624f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Nov 2004 11:06:36 +0100 Subject: ndb: bug#6451 1) fix so that missing blob tables don't prevent table from being dropped 2) decrease size of blob part if record length exceeds max length 3) add test case for table wo/ corresponding blob table 4) init scan counters when sending scan_tabreq mysql-test/r/ndb_autodiscover.result: testcase for table wo/ corresponding blob tables mysql-test/r/ndb_autodiscover2.result: testcase for table wo/ corresponding blob tables mysql-test/t/ndb_autodiscover.test: testcase for table wo/ corresponding blob tables mysql-test/t/ndb_autodiscover2.test: testcase for table wo/ corresponding blob tables ndb/include/ndbapi/NdbDictionary.hpp: Add non-const get column ndb/src/ndbapi/NdbDictionary.cpp: Add non-const get column ndb/src/ndbapi/NdbDictionaryImpl.hpp: Allow "partially" getTable, which enables dropping of tables that fails to create blob tables ndb/src/ndbapi/NdbScanOperation.cpp: Init counter when sending SCAN_TABREQ sql/ha_ndbcluster.cc: Make sure that blob don't have to big part size --- sql/ha_ndbcluster.cc | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 838cf69855a..ddc073f79eb 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3307,7 +3307,7 @@ int ha_ndbcluster::create(const char *name, { NDBTAB tab; NDBCOL col; - uint pack_length, length, i; + uint pack_length, length, i, pk_length= 0; const void *data, *pack_data; const char **key_names= form->keynames.type_names; char name2[FN_HEADLEN]; @@ -3354,6 +3354,8 @@ int ha_ndbcluster::create(const char *name, if ((my_errno= create_ndb_column(col, field, info))) DBUG_RETURN(my_errno); tab.addColumn(col); + if(col.getPrimaryKey()) + pk_length += (field->pack_length() + 3) / 4; } // No primary key, create shadow key as 64 bit, auto increment @@ -3367,6 +3369,39 @@ int ha_ndbcluster::create(const char *name, col.setPrimaryKey(TRUE); col.setAutoIncrement(TRUE); tab.addColumn(col); + pk_length += 2; + } + + // Make sure that blob tables don't have to big part size + for (i= 0; i < form->fields; i++) + { + /** + * The extra +7 concists + * 2 - words from pk in blob table + * 5 - from extra words added by tup/dict?? + */ + switch (form->field[i]->real_type()) { + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + { + NdbDictionary::Column * col = tab.getColumn(i); + int size = pk_length + (col->getPartSize()+3)/4 + 7; + if(size > NDB_MAX_TUPLE_SIZE_IN_WORDS && + (pk_length+7) < NDB_MAX_TUPLE_SIZE_IN_WORDS) + { + size = NDB_MAX_TUPLE_SIZE_IN_WORDS - pk_length - 7; + col->setPartSize(4*size); + } + /** + * If size > NDB_MAX and pk_length+7 >= NDB_MAX + * then the table can't be created anyway, so skip + * changing part size, and have error later + */ + } + default: + break; + } } if ((my_errno= check_ndb_connection())) -- cgit v1.2.1 From 7240a4d317cca5ccc08f7c1fb10f71d9b8f23d55 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Nov 2004 11:11:49 +0100 Subject: ndb: bug#6435 fix null handling in ha_ndbcluster when using ordered index mysql-test/r/ndb_index_ordered.result: bug#6435 mysql-test/t/ndb_index_ordered.test: bug#6435 sql/ha_ndbcluster.cc: Fix null handling in ordered index code --- sql/ha_ndbcluster.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index ddc073f79eb..893a6a022cd 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1290,7 +1290,6 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, Field *field= key_part->field; uint part_len= key_part->length; uint part_store_len= key_part->store_length; - bool part_nullable= (bool) key_part->null_bit; // Info about each key part struct part_st { bool part_last; @@ -1312,9 +1311,9 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, p.part_last= (tot_len + part_store_len >= key_tot_len[j]); p.key= keys[j]; p.part_ptr= &p.key->key[tot_len]; - p.part_null= (field->maybe_null() && *p.part_ptr); + p.part_null= key_part->null_bit && *p.part_ptr; p.bound_ptr= (const char *) - p.part_null ? 0 : part_nullable ? p.part_ptr + 1 : p.part_ptr; + p.part_null ? 0 : key_part->null_bit ? p.part_ptr + 1 : p.part_ptr; if (j == 0) { -- cgit v1.2.1 From 06cf873d8f14b6963e2cccf5ca4a214caeb94977 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Nov 2004 14:23:14 +0400 Subject: alter_table.result, alter_table.test, field_conv.cc: Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns Fix: use do_conv_blob rather than do_copy_blob if the column's character sets are different. sql/field_conv.cc: Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns Fix: use do_conv_blob rather than do_copy_blob if the column's character sets are different. mysql-test/t/alter_table.test: Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns Fix: use do_conv_blob rather than do_copy_blob if the column's character sets are different. mysql-test/r/alter_table.result: Bug #6479 ALTER TABLE ... changing charset fails for TEXT columns Fix: use do_conv_blob rather than do_copy_blob if the column's character sets are different. --- sql/field_conv.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sql') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 890687fc925..8a36fcd153c 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -475,6 +475,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) { if (!(from->flags & BLOB_FLAG)) return do_conv_blob; + if (from->charset() != to->charset()) + return do_conv_blob; if (from_length != to_length || to->table->db_low_byte_first != from->table->db_low_byte_first) { -- cgit v1.2.1 From c4d04e9ec112e5df429844934507488c2c3990b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Nov 2004 21:45:23 +0100 Subject: As rollback can be 30 times slower than insert in InnoDB, and user may not know there's rollback (if it's because of a dupl row), better warn that it's happening. It can also be of use for a DBA killing a connection and wondering what this connection is still doing now. Example: | 5 | root | localhost | test | Killed | 10 | Rolling back | insert into i select * from j | sql/handler.cc: As rollback can be 30 times slower than insert in InnoDB, and user may not know there's rollback (if it's because of a dupl row), better warn. --- sql/handler.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index f7a1a6ef0bf..cb88ab463d8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -581,6 +581,12 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) if (opt_using_transactions) { bool operation_done=0; + /* + As rollback can be 30 times slower than insert in InnoDB, and user may + not know there's rollback (if it's because of a dupl row), better warn. + */ + const char *save_proc_info= thd->proc_info; + thd->proc_info= "Rolling back"; #ifdef HAVE_NDBCLUSTER_DB if (trans->ndb_tid) { @@ -652,6 +658,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) thd->variables.tx_isolation=thd->session_tx_isolation; if (operation_done) statistic_increment(ha_rollback_count,&LOCK_status); + thd->proc_info= save_proc_info; } #endif /* USING_TRANSACTIONS */ DBUG_RETURN(error); -- cgit v1.2.1 From 8e8c1a4756f04b582893965af0b780c2d32536f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Nov 2004 03:20:58 +0200 Subject: Simple optimization --- sql/field.cc | 13 ++++++++++--- sql/field_conv.cc | 4 +--- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 1111e47bc38..deb38048d42 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4390,6 +4390,8 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)), int Field_string::cmp(const char *a_ptr, const char *b_ptr) { + uint a_len, b_len; + if (field_charset->strxfrm_multiply > 1) { /* @@ -4401,9 +4403,14 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) (const uchar*) b_ptr, field_length); } - uint char_len= field_length/field_charset->mbmaxlen; - uint a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len); - uint b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len); + if (field_charset->mbmaxlen != 1) + { + uint char_len= field_length/field_charset->mbmaxlen; + a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len); + b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len); + } + else + a_len= b_len= field_length; return my_strnncoll(field_charset,(const uchar*) a_ptr, a_len, (const uchar*) b_ptr, b_len); } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 8a36fcd153c..61a5a28f47b 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -473,9 +473,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) { if (to->flags & BLOB_FLAG) { - if (!(from->flags & BLOB_FLAG)) - return do_conv_blob; - if (from->charset() != to->charset()) + if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset()) return do_conv_blob; if (from_length != to_length || to->table->db_low_byte_first != from->table->db_low_byte_first) -- cgit v1.2.1 From a9c7e3179cb9b0861943f0b0c4c9d38614c44536 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Nov 2004 14:46:26 +0200 Subject: Fix for valgrind/purify for variables that the compiler touches but that doesn't affect the outcome of the tests --- sql/item_timefunc.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 41418c0094d..d8142352e70 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -161,21 +161,24 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, { int weekday= 0, yearday= 0, daypart= 0; int week_number= -1; - CHARSET_INFO *cs= &my_charset_bin; int error= 0; - bool usa_time= 0; - bool sunday_first_n_first_week_non_iso= -2; - bool strict_week_number; int strict_week_number_year= -1; - bool strict_week_number_year_type= -1; int frac_part; + bool usa_time= 0; + bool sunday_first_n_first_week_non_iso; + bool strict_week_number; + bool strict_week_number_year_type; const char *val_begin= val; const char *val_end= val + length; const char *ptr= format->format.str; const char *end= ptr + format->format.length; + CHARSET_INFO *cs= &my_charset_bin; DBUG_ENTER("extract_date_time"); LINT_INIT(strict_week_number); + /* Remove valgrind varnings when using gcc 3.3 and -O1 */ + PURIFY_OR_LINT_INIT(strict_week_number_year_type); + PURIFY_OR_LINT_INIT(sunday_first_n_first_week_non_iso); if (!sub_pattern_end) bzero((char*) l_time, sizeof(*l_time)); -- cgit v1.2.1 From afbb5d8fac43708862b32f02c9cf82db1650eed7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Nov 2004 17:56:33 +0200 Subject: WL#1972 "Evaluate HAVING before SELECT select-list" - post-review fix regarding Item_fields - added test for the changed name resolution mysql-test/r/having.result: Test for changed name resolution of Item_fields mysql-test/t/having.test: Test for changed name resolution of Item_fields sql/item.cc: - Changed Item_field::fix_fields to perform the same name resolution as Item_ref::fix_fields because column references of subqueries inside HAVING may be represented as Item_fields, and they need to be resolved as Item_refs. - Adjusted Item_field::fix_fields so that it has the same variable names and structure as Item_ref::fix_fields. --- sql/item.cc | 604 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 306 insertions(+), 298 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 8b611f0ddb5..919bce36280 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1390,113 +1390,312 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, } -bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) +/* + Search a GROUP BY clause for a field with a certain name. + + SYNOPSIS + find_field_in_group_list() + find_item the item being searched for + group_list GROUP BY clause + + DESCRIPTION + Search the GROUP BY list for a column named as find_item. When searching + preference is given to columns that are qualified with the same table (and + database) name as the one being searched for. + + RETURN + - the found item on success + - NULL if find_item is not in group_list +*/ + +static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) +{ + const char *db_name; + const char *table_name; + const char *field_name; + ORDER *found_group= NULL; + int found_match_degree= 0; + Item_field *cur_field; + int cur_match_degree= 0; + + if (find_item->type() == Item::FIELD_ITEM || + find_item->type() == Item::REF_ITEM) + { + db_name= ((Item_ident*) find_item)->db_name; + table_name= ((Item_ident*) find_item)->table_name; + field_name= ((Item_ident*) find_item)->field_name; + } + else + return NULL; + + DBUG_ASSERT(field_name); + + for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next) + { + if ((*(cur_group->item))->type() == Item::FIELD_ITEM) + { + cur_field= (Item_field*) *cur_group->item; + cur_match_degree= 0; + + DBUG_ASSERT(cur_field->field_name); + + if (!my_strcasecmp(system_charset_info, + cur_field->field_name, field_name)) + ++cur_match_degree; + else + continue; + + if (cur_field->table_name && table_name) + { + /* If field_name is qualified by a table name. */ + if (strcmp(cur_field->table_name, table_name)) + /* Same field names, different tables. */ + return NULL; + + ++cur_match_degree; + if (cur_field->db_name && db_name) + { + /* If field_name is also qualified by a database name. */ + if (strcmp(cur_field->db_name, db_name)) + /* Same field names, different databases. */ + return NULL; + ++cur_match_degree; + } + } + + if (cur_match_degree > found_match_degree) + { + found_match_degree= cur_match_degree; + found_group= cur_group; + } + else if (found_group && (cur_match_degree == found_match_degree) && + ! (*(found_group->item))->eq(cur_field, 0)) + { + /* + If the current resolve candidate matches equally well as the current + best match, they must reference the same column, otherwise the field + is ambiguous. + */ + my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), + MYF(0), find_item->full_name(), current_thd->where); + return NULL; + } + } + } + + if (found_group) + return found_group->item; + else + return NULL; +} + + +/* + Resolve a column reference in a sub-select. + + SYNOPSIS + resolve_ref_in_select_and_group() + thd current thread + ref column reference being resolved + select the sub-select that ref is resolved against + + DESCRIPTION + Resolve a column reference (usually inside a HAVING clause) against the + SELECT and GROUP BY clauses of the query described by 'select'. The name + resolution algorithm searches both the SELECT and GROUP BY clauses, and in + case of a name conflict prefers GROUP BY column names over SELECT names. If + both clauses contain different fields with the same names, a warning is + issued that name of 'ref' is ambiguous. We extend ANSI SQL in that when no + GROUP BY column is found, then a HAVING name is resolved as a possibly + derived SELECT column. + + NOTES + The resolution procedure is: + - Search for a column or derived column named col_ref_i [in table T_j] + in the SELECT clause of Q. + - Search for a column named col_ref_i [in table T_j] + in the GROUP BY clause of Q. + - If found different columns with the same name in GROUP BY and SELECT + - issue a warning and return the GROUP BY column, + - otherwise return the found SELECT column. + + + RETURN + NULL - there was an error, and the error was already reported + not_found_item - the item was not resolved, no error was reported + resolved item - if the item was resolved +*/ + +static Item** +resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) +{ + Item **group_by_ref= NULL; + Item **select_ref= NULL; + ORDER *group_list= (ORDER*) select->group_list.first; + bool ambiguous_fields= FALSE; + uint counter; + + /* + Search for a column or derived column named as 'ref' in the SELECT + clause of the current select. + */ + if (!(select_ref= find_item_in_list(ref, *(select->get_item_list()), &counter, + REPORT_EXCEPT_NOT_FOUND))) + return NULL; /* Some error occurred. */ + + /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ + if (select->having_fix_field && !ref->with_sum_func && group_list) + { + group_by_ref= find_field_in_group_list(ref, group_list); + + /* Check if the fields found in SELECT and GROUP BY are the same field. */ + if (group_by_ref && (select_ref != not_found_item) && + !((*group_by_ref)->eq(*select_ref, 0))) + { + ambiguous_fields= TRUE; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR, + ER(ER_NON_UNIQ_ERROR), ref->full_name(), + current_thd->where); + + } + } + + if (select_ref != not_found_item || group_by_ref) + { + if (select_ref != not_found_item && !ambiguous_fields) + { + if (*select_ref && !(*select_ref)->fixed) + { + my_error(ER_ILLEGAL_REFERENCE, MYF(0), ref->name, + "forward reference in item list"); + return NULL; + } + return (select->ref_pointer_array + counter); + } + else if (group_by_ref) + return group_by_ref; + else + DBUG_ASSERT(FALSE); + } + else + return (Item**) not_found_item; +} + + +bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { DBUG_ASSERT(fixed == 0); if (!field) // If field is not checked { - bool upward_lookup= 0; - Field *tmp= (Field *)not_found_field; - if ((tmp= find_field_in_tables(thd, this, tables, ref, + bool upward_lookup= FALSE; + Field *from_field= (Field *)not_found_field; + if ((from_field= find_field_in_tables(thd, this, tables, reference, IGNORE_EXCEPT_NON_UNIQUE, !any_privileges)) == not_found_field) { - /* - We can't find table field in table list of current select, - consequently we have to find it in outer subselect(s). - We can't join lists of outer & current select, because of scope - of view rules. For example if both tables (outer & current) have - field 'field' it is not mistake to refer to this field without - mention of table name, but if we join tables in one list it will - cause error ER_NON_UNIQ_ERROR in find_field_in_tables. - */ - SELECT_LEX *last= 0; #ifdef EMBEDDED_LIBRARY thd->net.last_errno= 0; #endif + SELECT_LEX *last= 0; TABLE_LIST *table_list; - Item **refer= (Item **)not_found_item; - uint counter; - // Prevent using outer fields in subselects, that is not supported now - SELECT_LEX *cursel= (SELECT_LEX *) thd->lex->current_select; - if (cursel->master_unit()->first_select()->linkage != DERIVED_TABLE_TYPE) + Item **ref= (Item **) not_found_item; + SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select; + /* + If there is an outer select, and it is not a derived table (which do + not support the use of outer fields for now), try to resolve this + reference in the outer select(s). + + We treat each subselect as a separate namespace, so that different + subselects may contain columns with the same names. The subselects are + searched starting from the innermost. + */ + if (current_sel->master_unit()->first_select()->linkage != + DERIVED_TABLE_TYPE) { - SELECT_LEX_UNIT *prev_unit= cursel->master_unit(); - for (SELECT_LEX *sl= prev_unit->outer_select(); - sl; - sl= (prev_unit= sl->master_unit())->outer_select()) + SELECT_LEX_UNIT *prev_unit= current_sel->master_unit(); + SELECT_LEX *outer_sel= prev_unit->outer_select(); + for ( ; outer_sel ; + outer_sel= (prev_unit= outer_sel->master_unit())->outer_select()) { - upward_lookup= 1; - table_list= (last= sl)->get_table_list(); - if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) - { + last= outer_sel; + Item_subselect *prev_subselect_item= prev_unit->item; + upward_lookup= TRUE; + + /* Search in the tables of the FROM clause of the outer select. */ + table_list= outer_sel->get_table_list(); + if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) /* - it is primary INSERT st_select_lex => skip first table - resolving + It is a primary INSERT st_select_lex => do not resolve against the + first table. */ table_list= table_list->next_local; - } - Item_subselect *prev_subselect_item= prev_unit->item; enum_parsing_place place= prev_subselect_item->parsing_place; /* - check table fields only if subquery used somewhere out of HAVING - or SELECT list or outer SELECT do not use groupping (i.e. tables - are accessable) + Check table fields only if the subquery is used somewhere out of + HAVING or SELECT list, or the outer SELECT does not use grouping + (i.e. tables are accessible). */ - if (((place != IN_HAVING && - place != SELECT_LIST) || - (sl->with_sum_func == 0 && sl->group_list.elements == 0)) && - (tmp= find_field_in_tables(thd, this, - table_list, ref, - IGNORE_EXCEPT_NON_UNIQUE, 1)) != + if (((place != IN_HAVING && place != SELECT_LIST) || + (outer_sel->with_sum_func == 0 && + outer_sel->group_list.elements == 0)) && + (from_field= find_field_in_tables(thd, this, table_list, + reference, + IGNORE_EXCEPT_NON_UNIQUE, + TRUE)) != not_found_field) { - if (tmp) + if (from_field) { - if (tmp != view_ref_found) + if (from_field != view_ref_found) { - prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->used_tables_cache|= from_field->table->map; prev_subselect_item->const_item_cache= 0; } else { prev_subselect_item->used_tables_cache|= - (*ref)->used_tables(); + (*reference)->used_tables(); prev_subselect_item->const_item_cache&= - (*ref)->const_item(); + (*reference)->const_item(); } } break; } - if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && - (refer= find_item_in_list(this, sl->item_list, &counter, - REPORT_EXCEPT_NOT_FOUND)) != - (Item **) not_found_item) + + /* Search in the SELECT and GROUP lists of the outer select. */ + if (outer_sel->resolve_mode == SELECT_LEX::SELECT_MODE) { - if (*refer && (*refer)->fixed) // Avoid crash in case of error - { - prev_subselect_item->used_tables_cache|= (*refer)->used_tables(); - prev_subselect_item->const_item_cache&= (*refer)->const_item(); - } - break; + if (!(ref= resolve_ref_in_select_and_group(thd, this, outer_sel))) + return TRUE; /* Some error occured (e.g. ambigous names). */ + if (ref != not_found_item) + { + DBUG_ASSERT(*ref && (*ref)->fixed); + /* + Avoid crash in case of error. + TODO: what does this comment mean? + */ + prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); + prev_subselect_item->const_item_cache&= (*ref)->const_item(); + break; + } } // Reference is not found => depend from outer (or just error) prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; prev_subselect_item->const_item_cache= 0; - if (sl->master_unit()->first_select()->linkage == + if (outer_sel->master_unit()->first_select()->linkage == DERIVED_TABLE_TYPE) break; // do not look over derived table } } - if (!tmp) - return -1; - if (!refer) - return 1; - if (tmp == not_found_field && refer == (Item **)not_found_item) + + DBUG_ASSERT(ref); + if (!from_field) + return TRUE; + if (ref == not_found_item && from_field == not_found_field) { if (upward_lookup) { @@ -1507,59 +1706,54 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) else { // Call to report error - find_field_in_tables(thd, this, tables, ref, REPORT_ALL_ERRORS, 1); + find_field_in_tables(thd, this, tables, reference, REPORT_ALL_ERRORS, + TRUE); } - return -1; + return TRUE; } - else if (refer != (Item **)not_found_item) + else if (ref != not_found_item) { - if (!(*refer)->fixed) - { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); - return -1; - } + /* Should be checked in resolve_ref_in_select_and_group(). */ + DBUG_ASSERT(*ref && (*ref)->fixed); Item_ref *rf; - *ref= rf= new Item_ref(last->ref_pointer_array + counter, - ref, - (char *)table_name, - (char *)field_name); - register_item_tree_changing(ref); + *reference= rf= new Item_ref(ref, reference, (char *) table_name, + (char *) field_name); + register_item_tree_changing(reference); if (!rf) - return 1; + return TRUE; /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() */ - if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1)) - return 1; + if (rf->fix_fields(thd, tables, reference) || rf->check_cols(1)) + return TRUE; - mark_as_dependent(thd, last, cursel, rf); - return 0; + mark_as_dependent(thd, last, current_sel, rf); + return FALSE; } else { - mark_as_dependent(thd, last, cursel, this); + mark_as_dependent(thd, last, current_sel, this); if (last->having_fix_field) { Item_ref *rf; - *ref= rf= new Item_ref(ref, *ref, - (cached_table->db[0]?cached_table->db:0), - (char *)cached_table->alias, - (char *)field_name); + *reference= rf= new Item_ref(reference, *reference, + (cached_table->db[0]?cached_table->db:0), + (char *)cached_table->alias, + (char *)field_name); if (!rf) - return 1; + return TRUE; /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() */ - return rf->fix_fields(thd, tables, ref) || rf->check_cols(1); + return rf->fix_fields(thd, tables, reference) || rf->check_cols(1); } } } - else if (!tmp) - return -1; + else if (!from_field) + return TRUE; /* if it is not expression from merged VIEW we will set this field. @@ -1573,8 +1767,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Also we suppose that view can't be changed during PS/SP life. */ - if (tmp != view_ref_found) - set_field(tmp); + if (from_field != view_ref_found) + set_field(from_field); } else if (thd->set_query_id && field->query_id != thd->query_id) { @@ -1610,12 +1804,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) thd->host_or_ip, field_name, tab); - return 1; + return TRUE; } } #endif fixed= 1; - return 0; + return FALSE; } void Item_field::cleanup() @@ -2265,197 +2459,6 @@ bool Item_field::send(Protocol *protocol, String *buffer) } -/* - Search a GROUP BY clause for a field with a certain name. - - SYNOPSIS - find_field_in_group_list() - find_item the item being searched for - group_list GROUP BY clause - - DESCRIPTION - Search the GROUP BY list for a column named as find_item. When searching - preference is given to columns that are qualified with the same table (and - database) name as the one being searched for. - - RETURN - - the found item on success - - NULL if find_item is not in group_list -*/ - -static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) -{ - const char *db_name; - const char *table_name; - const char *field_name; - ORDER *found_group= NULL; - int found_match_degree= 0; - Item_field *cur_field; - int cur_match_degree= 0; - - if (find_item->type() == Item::FIELD_ITEM || - find_item->type() == Item::REF_ITEM) - { - db_name= ((Item_ident*) find_item)->db_name; - table_name= ((Item_ident*) find_item)->table_name; - field_name= ((Item_ident*) find_item)->field_name; - } - else - return NULL; - - DBUG_ASSERT(field_name); - - for (ORDER *cur_group= group_list ; cur_group ; cur_group= cur_group->next) - { - if ((*(cur_group->item))->type() == Item::FIELD_ITEM) - { - cur_field= (Item_field*) *cur_group->item; - cur_match_degree= 0; - - DBUG_ASSERT(cur_field->field_name); - - if (!my_strcasecmp(system_charset_info, - cur_field->field_name, field_name)) - ++cur_match_degree; - else - continue; - - if (cur_field->table_name && table_name) - { - /* If field_name is qualified by a table name. */ - if (strcmp(cur_field->table_name, table_name)) - /* Same field names, different tables. */ - return NULL; - - ++cur_match_degree; - if (cur_field->db_name && db_name) - { - /* If field_name is also qualified by a database name. */ - if (strcmp(cur_field->db_name, db_name)) - /* Same field names, different databases. */ - return NULL; - ++cur_match_degree; - } - } - - if (cur_match_degree > found_match_degree) - { - found_match_degree= cur_match_degree; - found_group= cur_group; - } - else if (found_group && (cur_match_degree == found_match_degree) && - ! (*(found_group->item))->eq(cur_field, 0)) - { - /* - If the current resolve candidate matches equally well as the current - best match, they must reference the same column, otherwise the field - is ambiguous. - */ - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - MYF(0), find_item->full_name(), current_thd->where); - return NULL; - } - } - } - - if (found_group) - return found_group->item; - else - return NULL; -} - - -/* - Resolve a column reference in a sub-select. - - SYNOPSIS - resolve_ref_in_select_and_group() - thd current thread - ref column reference being resolved - select the sub-select that ref is resolved against - - DESCRIPTION - Resolve a column reference (usually inside a HAVING clause) against the - SELECT and GROUP BY clauses of the query described by 'select'. The name - resolution algorithm searches both the SELECT and GROUP BY clauses, and in - case of a name conflict prefers GROUP BY column names over SELECT names. If - both clauses contain different fields with the same names, a warning is - issued that name of 'ref' is ambiguous. We extend ANSI SQL in that when no - GROUP BY column is found, then a HAVING name is resolved as a possibly - derived SELECT column. - - NOTES - The resolution procedure is: - - Search for a column or derived column named col_ref_i [in table T_j] - in the SELECT clause of Q. - - Search for a column named col_ref_i [in table T_j] - in the GROUP BY clause of Q. - - If found different columns with the same name in GROUP BY and SELECT - - issue a warning and return the GROUP BY column, - - otherwise return the found SELECT column. - - - RETURN - NULL - there was an error, and the error was already reported - not_found_item - the item was not resolved, no error was reported - resolved item - if the item was resolved -*/ -static Item** -resolve_ref_in_select_and_group(THD *thd, Item_ref *ref, SELECT_LEX *select) -{ - Item **group_by_ref= NULL; - Item **select_ref= NULL; - ORDER *group_list= (ORDER*) select->group_list.first; - bool ambiguous_fields= FALSE; - uint counter; - - /* - Search for a column or derived column named as 'ref' in the SELECT - clause of the current select. - */ - if (!(select_ref= find_item_in_list(ref, *(select->get_item_list()), &counter, - REPORT_EXCEPT_NOT_FOUND))) - return NULL; /* Some error occurred. */ - - /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ - if (select->having_fix_field && !ref->with_sum_func && group_list) - { - group_by_ref= find_field_in_group_list(ref, group_list); - - /* Check if the fields found in SELECT and GROUP BY are the same field. */ - if (group_by_ref && (select_ref != not_found_item) && - !((*group_by_ref)->eq(*select_ref, 0))) - { - ambiguous_fields= TRUE; - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR, - ER(ER_NON_UNIQ_ERROR), ref->full_name(), - current_thd->where); - - } - } - - if (select_ref != not_found_item || group_by_ref) - { - if (select_ref != not_found_item && !ambiguous_fields) - { - if (*select_ref && !(*select_ref)->fixed) - { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), ref->name, - "forward reference in item list"); - return NULL; - } - return (select->ref_pointer_array + counter); - } - else if (group_by_ref) - return group_by_ref; - else - DBUG_ASSERT(FALSE); - } - else - return (Item**) not_found_item; -} - - /* Resolve the name of a column reference. @@ -2539,7 +2542,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) DERIVED_TABLE_TYPE)) { TABLE_LIST *table_list; - Field *tmp= (Field*) not_found_field; + Field *from_field= (Field*) not_found_field; SELECT_LEX *last= 0; for ( ; outer_sel ; @@ -2569,14 +2572,16 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) /* Search in the tables of the FROM clause of the outer select. */ table_list= outer_sel->get_table_list(); if (outer_sel->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) - { - /* It is primary INSERT st_select_lex => skip the first table. */ + /* + It is a primary INSERT st_select_lex => do not resolve against the + first table. + */ table_list= table_list->next_local; - } + enum_parsing_place place= prev_subselect_item->parsing_place; /* Check table fields only if the subquery is used somewhere out of - HAVING or SELECT list, or outer SELECT does not use grouping + HAVING or SELECT list, or the outer SELECT does not use grouping (i.e. tables are accessible). TODO: Here we could first find the field anyway, and then test this @@ -2588,13 +2593,15 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) (!outer_sel->with_sum_func && outer_sel->group_list.elements == 0))) { - if ((tmp= find_field_in_tables(thd, this, table_list, reference, - IGNORE_EXCEPT_NON_UNIQUE, TRUE)) != + if ((from_field= find_field_in_tables(thd, this, table_list, + reference, + IGNORE_EXCEPT_NON_UNIQUE, + TRUE)) != not_found_field) { - if (tmp != view_ref_found) + if (from_field != view_ref_found) { - prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->used_tables_cache|= from_field->table->map; prev_subselect_item->const_item_cache= 0; } else @@ -2618,21 +2625,21 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } DBUG_ASSERT(ref); - if (!tmp) + if (!from_field) return TRUE; - else if (ref == not_found_item && tmp == not_found_field) + if (ref == not_found_item && from_field == not_found_field) { my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), this->full_name(), current_thd->where); ref= 0; return TRUE; } - else if (tmp != not_found_field) + else if (from_field != not_found_field) { ref= 0; // To prevent "delete *ref;" on ~Item_ref() of this item - if (tmp != view_ref_found) + if (from_field != view_ref_found) { - Item_field* fld= new Item_field(tmp); + Item_field* fld= new Item_field(from_field); if (!((*reference)= fld)) return TRUE; mark_as_dependent(thd, last, current_sel, fld); @@ -2652,6 +2659,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } else { + /* Should be checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->fixed); mark_as_dependent(thd, last, current_sel, this); } -- cgit v1.2.1 From 7d09ee39b00a34d798b1a4082cec3798cf12952b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 11:02:51 +0100 Subject: bug#6538 ndb: Fix return value in index_last wo/ rows sql/ha_ndbcluster.cc: Return correct when not finding any row from index_last --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 0d2b1676e3a..5971c1a6c2a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2318,7 +2318,7 @@ int ha_ndbcluster::index_last(byte *buf) DBUG_RETURN(0); } } - DBUG_RETURN(1); + DBUG_RETURN(res); } -- cgit v1.2.1 From c5e6941e75454a01953ff542ceda7e4aeb1c22ae Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 14:05:28 +0400 Subject: 1. When mixing NULL to a character string, the result takes its charset/collation attributes from the character string, e.g. SELECT func(NULL, _latin2'string') now returns a latin2 result. This is done by introducing a new derivation (aka coercibility) level DERIVATION_IGNORABLE, which is used with Item_null. 2. 'Pure' NULL is now BINARY(0), not CHAR(0). I.e. NULL is now more typeless. mysql-test/r/metadata.result: Fixing test results: CHAR(0) -> BINARY(0) for NULLs mysql-test/r/null.result: Testing mixing NULL with a character string with a number of functions. mysql-test/r/ps_2myisam.result: Fixing test results: CHAR(0) -> BINARY(0) for NULLs mysql-test/r/ps_3innodb.result: Fixing test results: CHAR(0) -> BINARY(0) for NULLs mysql-test/r/ps_4heap.result: Fixing test results: CHAR(0) -> BINARY(0) for NULLs mysql-test/r/ps_5merge.result: Fixing test results: CHAR(0) -> BINARY(0) for NULLs mysql-test/r/ps_6bdb.result: Fixing test results: CHAR(0) -> BINARY(0) for NULLs mysql-test/r/ps_7ndb.result: Fixing test results: CHAR(0) -> BINARY(0) for NULLs mysql-test/t/null.test: Testing mixing NULL with a character string with a number of functions. sql/item.cc: New derivation level. sql/item.h: New derivation level. --- sql/item.cc | 4 ++-- sql/item.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index b4e7322b7cc..0e7a2b50b51 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -376,13 +376,13 @@ bool DTCollation::aggregate(DTCollation &dt, uint flags) } else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && derivation < dt.derivation && - dt.derivation == DERIVATION_COERCIBLE) + dt.derivation >= DERIVATION_COERCIBLE) { // Do nothing; } else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && dt.derivation < derivation && - derivation == DERIVATION_COERCIBLE) + derivation >= DERIVATION_COERCIBLE) { set(dt); strong= nagg; diff --git a/sql/item.h b/sql/item.h index fea3aa010a8..547577a7ee0 100644 --- a/sql/item.h +++ b/sql/item.h @@ -31,6 +31,7 @@ void item_init(void); /* Init item functions */ enum Derivation { + DERIVATION_IGNORABLE= 4, DERIVATION_COERCIBLE= 3, DERIVATION_IMPLICIT= 2, DERIVATION_NONE= 1, @@ -98,6 +99,7 @@ public: { switch(derivation) { + case DERIVATION_IGNORABLE: return "IGNORABLE"; case DERIVATION_COERCIBLE: return "COERCIBLE"; case DERIVATION_IMPLICIT: return "IMPLICIT"; case DERIVATION_EXPLICIT: return "EXPLICIT"; @@ -440,6 +442,7 @@ public: max_length= 0; name= name_par ? name_par : (char*) "NULL"; fixed= 1; + collation.set(&my_charset_bin, DERIVATION_IGNORABLE); } enum Type type() const { return NULL_ITEM; } bool eq(const Item *item, bool binary_cmp) const; -- cgit v1.2.1 From 69dcc5b43c61b2133bd0d18cb2de774a08eced9d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 12:43:08 +0200 Subject: WL#1972 "Evaluate HAVING before SELECT select-list" - post-review changes sql/item.cc: - more/improved comments --- sql/item.cc | 86 ++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 919bce36280..12b0f7b0796 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1564,7 +1564,8 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) { if (select_ref != not_found_item && !ambiguous_fields) { - if (*select_ref && !(*select_ref)->fixed) + DBUG_ASSERT(*select_ref); + if (! (*select_ref)->fixed) { my_error(ER_ILLEGAL_REFERENCE, MYF(0), ref->name, "forward reference in item list"); @@ -1582,6 +1583,58 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) } +/* + Resolve the name of a column reference. + + SYNOPSIS + Item_field::fix_fields() + thd [in] current thread + tables [in] the tables in a FROM clause + reference [in/out] view column if this item was resolved to a view column + + DESCRIPTION + The method resolves the column reference represented by 'this' as a column + present in one of: FROM clause, SELECT clause, GROUP BY clause of a query + Q, or in outer queries that contain Q. + + NOTES + The name resolution algorithm used is (where [T_j] is an optional table + name that qualifies the column name): + + resolve_column_reference([T_j].col_ref_i) + { + search for a column or derived column named col_ref_i + [in table T_j] in the FROM clause of Q; + + if such a column is NOT found AND // Lookup in outer queries. + there are outer queries + { + for each outer query Q_k beginning from the inner-most one + { + if - Q_k is not a group query AND + - Q_k is not inside an aggregate function + OR + - Q_(k-1) is not in a HAVING or SELECT clause of Q_k + { + search for a column or derived column named col_ref_i + [in table T_j] in the FROM clause of Q_k; + } + + if such a column is not found + Search for a column or derived column named col_ref_i + [in table T_j] in the SELECT and GROUP clauses of Q_k. + } + } + } + + Notice that compared to Item_ref::fix_fields, here we first search the FROM + clause, and then we search the SELECT and GROUP BY clauses. + + RETURN + TRUE if error + FALSE on success +*/ + bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { DBUG_ASSERT(fixed == 0); @@ -1672,10 +1725,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) if (ref != not_found_item) { DBUG_ASSERT(*ref && (*ref)->fixed); - /* - Avoid crash in case of error. - TODO: what does this comment mean? - */ prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); prev_subselect_item->const_item_cache&= (*ref)->const_item(); break; @@ -1699,7 +1748,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { if (upward_lookup) { - // We can't say exactly what absend table or field + // We can't say exactly what absent table or field my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), full_name(), thd->where); } @@ -2460,12 +2509,12 @@ bool Item_field::send(Protocol *protocol, String *buffer) /* - Resolve the name of a column reference. + Resolve the name of a reference to a column reference. SYNOPSIS Item_ref::fix_fields() thd [in] current thread - tables [in] the tables in the FROM clause + tables [in] the tables in a FROM clause reference [in/out] view column if this item was resolved to a view column DESCRIPTION @@ -2475,7 +2524,8 @@ bool Item_field::send(Protocol *protocol, String *buffer) aggregate functions. NOTES - The name resolution algorithm used is: + The name resolution algorithm used is (where [T_j] is an optional table + name that qualifies the column name): resolve_extended([T_j].col_ref_i) { @@ -2504,7 +2554,9 @@ bool Item_field::send(Protocol *protocol, String *buffer) } This procedure treats GROUP BY and SELECT clauses as one namespace for - column references in HAVING. + column references in HAVING. Notice that compared to + Item_field::fix_fields, here we first search the SELECT and GROUP BY + clauses, and then we search the FROM clause. RETURN TRUE if error @@ -2559,10 +2611,6 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) if (ref != not_found_item) { DBUG_ASSERT(*ref && (*ref)->fixed); - /* - Avoid crash in case of error. - TODO: what does this comment mean? - */ prev_subselect_item->used_tables_cache|= (*ref)->used_tables(); prev_subselect_item->const_item_cache&= (*ref)->const_item(); break; @@ -2675,13 +2723,9 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } /* - The following conditional is changed as to correctly identify - incorrect references in group functions or forward references - with sub-select's / derived tables, while it prevents this - check when Item_ref is created in an expression involving - summing function, which is to be placed in the user variable. - - TODO: this comment is impossible to understand. + Check if this is an incorrect reference in a group function or forward + reference. Do not issue an error if this is an unnamed reference inside an + aggregate function. */ if (((*ref)->with_sum_func && name && (depended_from || -- cgit v1.2.1 From 12fbc41f5f76b84cf6b7f174f0b9d27e187d104b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 15:07:55 +0100 Subject: Fix for BUG#6522 "Replication fails due to a rolled back transaction in the binlog" When we are writing a transaction to the binlog, we log BEGIN/COMMIT with zero error code. Example: all statements of trans succeeded, connection lost and so implicit rollback: we don't want ER_NET* errors to be logged in the BEGIN/ROLLBACK events, while statement events have 0. If there was really a serious error code, it's already in the statement events. sql/log.cc: When we write the cached binlog segment to disk binlog at COMMIT/ROLLBACK time: imagine this is rollback due to net timeout, after all statements of the transaction succeeded. Then we want a zero-error code in BEGIN. In other words, if there was a really serious error code it's already in the transaction's statement events. sql/sql_table.cc: out of date comment --- sql/log.cc | 9 +++++++++ sql/sql_table.cc | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index aa5d9d8753b..b2d015c1a14 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1370,6 +1370,14 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) */ { Query_log_event qinfo(thd, "BEGIN", 5, TRUE); + /* + Imagine this is rollback due to net timeout, after all statements of + the transaction succeeded. Then we want a zero-error code in BEGIN. + In other words, if there was a really serious error code it's already + in the statement's events. + This is safer than thd->clear_error() against kills at shutdown. + */ + qinfo.error_code= 0; /* Now this Query_log_event has artificial log_pos 0. It must be adjusted to reflect the real position in the log. Not doing it would confuse the @@ -1403,6 +1411,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) commit_or_rollback ? "COMMIT" : "ROLLBACK", commit_or_rollback ? 6 : 8, TRUE); + qinfo.error_code= 0; qinfo.set_log_pos(this); if (qinfo.write(&log_file) || flush_io_cache(&log_file)) goto err; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 65690e56039..1e5237b1428 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -911,7 +911,6 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } table->file->extra(HA_EXTRA_WRITE_CACHE); DBUG_RETURN(table); - /* Note that leaving the function resets binlogging properties */ } -- cgit v1.2.1 From 97af0a0e8f3353cc849b33bf5b733764da7cb202 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 15:07:11 +0000 Subject: Bug#6031 - To drop database you have to execute DROP DATABASE command twice. DROP DATABASE failed because of file ext not in TYPELIB of known extensions. General solution - construct a TYPELIB at runtime instead of a static list. mysql-test/r/ndb_basic.result: Bug#6031 New test for bug mysql-test/t/ndb_basic.test: Bug#6031 New test for bug sql/ha_ndbcluster.cc: Cosmetic fix sql/handler.cc: Bug#6031 New function - ha_known_exts() We can construct TYPELIB of known db file extensions. sql/handler.h: Bug#6031 New function - ha_known_exts() sql/sql_db.cc: Bug#6031 We use a constructed list of known extensions instead of a static list --- sql/ha_ndbcluster.cc | 2 +- sql/handler.cc | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/handler.h | 2 +- sql/sql_db.cc | 7 +------ 4 files changed, 59 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 5971c1a6c2a..d9545d5cbb8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2777,7 +2777,7 @@ int ha_ndbcluster::reset() const char **ha_ndbcluster::bas_ext() const -{ static const char *ext[]= { ".ndb", NullS }; return ext; } +{ static const char *ext[]= { ha_ndb_ext, NullS }; return ext; } /* diff --git a/sql/handler.cc b/sql/handler.cc index f7a1a6ef0bf..2c274c7989e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -109,6 +109,8 @@ const char *tx_isolation_names[] = TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", tx_isolation_names, NULL}; +static TYPELIB known_extensions= {0,"known_exts", NULL, NULL}; + enum db_type ha_resolve_by_name(const char *name, uint namelen) { THD *thd=current_thd; @@ -1633,3 +1635,57 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key, return error; } +/* + Returns a list of all known extensions. + + SYNOPSIS + ha_known_exts() + + NOTES + No mutexes, worst case race is a minor surplus memory allocation + + RETURN VALUE + pointer pointer to TYPELIB structure +*/ +TYPELIB *ha_known_exts(void) +{ + if (!known_extensions.type_names) + { + show_table_type_st *types; + List found_exts; + List_iterator_fast it(found_exts); + const char *e, **ext; + + found_exts.push_back(".db"); + for (types= sys_table_types; types->type; types++) + { + if (*types->value == SHOW_OPTION_YES) + { + handler *file= get_new_handler(0,(enum db_type) types->db_type); + for (ext= file->bas_ext(); *ext; ext++) + { + while (e=it++) + if (e == *ext) + break; + + if (!e) + found_exts.push_back((char *)*ext); + + it.rewind(); + } + delete file; + } + } + ext= (const char **)my_once_alloc(sizeof(char *)* + (found_exts.elements+1), MYF(MY_WME)); + + DBUG_ASSERT(ext); + for (uint i=0; e=it++; i++) + ext[i]= e; + ext[found_exts.elements]= 0; + + known_extensions.count= found_exts.elements; + known_extensions.type_names= ext; + } + return &known_extensions; +} diff --git a/sql/handler.h b/sql/handler.h index a7ce4e708fd..54a416d80ad 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -567,5 +567,5 @@ int ha_discover(THD* thd, const char* dbname, const char* name, int ha_find_files(THD *thd,const char *db,const char *path, const char *wild, bool dir,List* files); int ha_table_exists(THD* thd, const char* db, const char* name); - +TYPELIB *ha_known_exts(void); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index e50796f2a33..350a7432990 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -30,11 +30,6 @@ const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; -const char *known_exts[]= -{".ISM",".ISD",".ISM",".MRG",".MYI",".MYD",".db", ".ibd", NullS}; -static TYPELIB known_extentions= -{array_elements(known_exts)-1,"known_exts", known_exts, NULL}; - static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, const char *path, uint level); @@ -737,7 +732,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, extension= fn_ext(file->name); if (find_type(extension, &deletable_extentions,1+2) <= 0) { - if (find_type(extension, &known_extentions,1+2) <= 0) + if (find_type(extension, ha_known_exts(),1+2) <= 0) found_other_files++; continue; } -- cgit v1.2.1 From 69bce9c68d2dd38bc4cb58b19fbf609aca11e5dd Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 18:07:39 +0200 Subject: More debugging Print position in normal log for Binlog dump dbug/dbug.c: Added DBUG_OUTPUT() to temporary start/stop trace-file output Optimized alignment of CODE_STATE structure include/my_dbug.h: Added DBUG_OUTPUT() to temporary start/stop trace-file output sql/field.cc: Safety fix when used with future 5.0 .frm tables sql/log.cc: More debugging sql/mysqld.cc: Fixed type sql/slave.cc: Fixed wrong cast (not a bug) sql/sql_class.h: More DBUG output sql/sql_parse.cc: Print position in normal log for Binlog dump --- sql/field.cc | 10 ++++++++-- sql/log.cc | 32 +++++++++++++++++++++++--------- sql/mysqld.cc | 2 +- sql/slave.cc | 2 +- sql/sql_class.h | 2 +- sql/sql_parse.cc | 11 +++++++---- 6 files changed, 41 insertions(+), 18 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index deb38048d42..f70a23e889a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5941,8 +5941,14 @@ Field *make_field(char *ptr, uint32 field_length, if (f_is_alpha(pack_flag)) { if (!f_is_packed(pack_flag)) - return new Field_string(ptr,field_length,null_pos,null_bit, - unireg_check, field_name, table, field_charset); + { + if (field_type == FIELD_TYPE_STRING || + field_type == FIELD_TYPE_VAR_STRING) + return new Field_string(ptr,field_length,null_pos,null_bit, + unireg_check, field_name, table, + field_charset); + return 0; // Error + } uint pack_length=calc_pack_length((enum_field_types) f_packtype(pack_flag), diff --git a/sql/log.cc b/sql/log.cc index ef57a57d3b4..bcd99326501 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1703,6 +1703,8 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, time_t current_time; if (!is_open()) return 0; + DBUG_ENTER("MYSQL_LOG::write"); + VOID(pthread_mutex_lock(&LOCK_log)); if (is_open()) { // Safety agains reopen @@ -1712,7 +1714,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, if (!(thd->options & OPTION_UPDATE_LOG)) { VOID(pthread_mutex_unlock(&LOCK_log)); - return 0; + DBUG_RETURN(0); } if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT) || query_start_arg) { @@ -1812,7 +1814,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, } } VOID(pthread_mutex_unlock(&LOCK_log)); - return error; + DBUG_RETURN(error); } @@ -1832,16 +1834,19 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, THD::enter_cond() (see NOTES in sql_class.h). */ -void MYSQL_LOG:: wait_for_update(THD* thd, bool master_or_slave) +void MYSQL_LOG::wait_for_update(THD* thd, bool master_or_slave) { - const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log, - master_or_slave ? - "Has read all relay log; waiting for \ -the slave I/O thread to update it" : - "Has sent all binlog to slave; \ -waiting for binlog to be updated"); + const char *old_msg; + DBUG_ENTER("wait_for_update"); + old_msg= thd->enter_cond(&update_cond, &LOCK_log, + master_or_slave ? + "Has read all relay log; waiting for the slave I/O " + "thread to update it" : + "Has sent all binlog to slave; waiting for binlog " + "to be updated"); pthread_cond_wait(&update_cond, &LOCK_log); thd->exit_cond(old_msg); + DBUG_VOID_RETURN; } @@ -2198,6 +2203,15 @@ void MYSQL_LOG::report_pos_in_innodb() DBUG_VOID_RETURN; } + +void MYSQL_LOG::signal_update() +{ + DBUG_ENTER("MYSQL_LOG::signal_update"); + pthread_cond_broadcast(&update_cond); + DBUG_VOID_RETURN; +} + + #ifdef __NT__ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, uint length, int buffLen) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 078ee19fe6a..5622ac50a7b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -540,7 +540,7 @@ static void close_connections(void) struct timespec abstime; int error; LINT_INIT(error); - DBUG_PRINT("info",("Waiting for select_thread")); + DBUG_PRINT("info",("Waiting for select thread")); #ifndef DONT_USE_THR_ALARM if (pthread_kill(select_thread,THR_CLIENT_ALARM)) diff --git a/sql/slave.cc b/sql/slave.cc index 4ef8715f1e6..ea1f3cceaf4 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2632,7 +2632,7 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi, DBUG_ENTER("request_dump"); // TODO if big log files: Change next to int8store() - int4store(buf, (longlong) mi->master_log_pos); + int4store(buf, (ulong) mi->master_log_pos); int2store(buf + 4, binlog_flags); int4store(buf + 6, server_id); len = (uint) strlen(logname); diff --git a/sql/sql_class.h b/sql/sql_class.h index df6be559df2..312d9de9794 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -131,7 +131,7 @@ public: DBUG_VOID_RETURN; } void set_max_size(ulong max_size_arg); - void signal_update() { pthread_cond_broadcast(&update_cond);} + void signal_update(); void wait_for_update(THD* thd, bool master_or_slave); void set_need_start_event() { need_start_event = 1; } void init(enum_log_type log_type_arg, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2bf977804af..226ead71ada 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1610,15 +1610,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #ifndef EMBEDDED_LIBRARY case COM_BINLOG_DUMP: { + ulong pos; + ushort flags; + uint32 slave_server_id; + statistic_increment(com_other,&LOCK_status); thd->slow_command = TRUE; if (check_global_access(thd, REPL_SLAVE_ACL)) break; - mysql_log.write(thd,command, 0); - ulong pos; - ushort flags; - uint32 slave_server_id; /* TODO: The following has to be changed to an 8 byte integer */ pos = uint4korr(packet); flags = uint2korr(packet + 4); @@ -1626,6 +1626,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0 kill_zombie_dump_threads(slave_server_id); thd->server_id = slave_server_id; + + mysql_log.write(thd, command, "Log: '%s' Pos: %ld", packet+10, + (long) pos); mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags); unregister_slave(thd,1,1); // fake COM_QUIT -- if we get here, the thread needs to terminate -- cgit v1.2.1 From 313ce62f7036d1626f248bc8cbb197ffc4a9001c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 17:56:45 +0100 Subject: WL#1596 "make mysqldump --master-data --single-transaction able to do online dump of InnoDB AND report reliable binlog coordinates corresponding to the dump". The good news is that now mysqldump can be used to get an online backup of InnoDB *which works for point-in-time recovery and replication slave creation*. Formerly, mysqldump --master-data --single-transaction used to call in fact mysqldump --master-data, so the dump was not an online dump (took big lock all time of dump). The only lock which is now taken in this patch is at the beginning of the dump: mysqldump does: FLUSH TABLES WITH READ LOCK; START TRANSACTION WITH CONSISTENT SNAPSHOT; SHOW MASTER STATUS; UNLOCK TABLES; so the lock time is in fact the time FLUSH TABLES WITH READ LOCK takes to return (can be 0 or very long, if a table is undergoing a huge update). I have done some more minor changes listed in the paragraph of mysqldump.c. WL#2237 "WITH CONSISTENT SNAPSHOT clause for START TRANSACTION": it's a START TRANSACTION which additionally starts a consistent read on all capable storage engine (i.e. InnoDB). So, can serve as a replacement for BEGIN; SELECT * FROM some_innodb_table LIMIT 1; which starts a consistent read too. client/mysqldump.c: Main change: mysqldump --single-transaction --master-data is now able to, at the same time, take an online dump of InnoDB (using consistent read) AND get the binlog position corresponding to this dump (before, using the two options used to silently cancel --single-transaction). This uses the new START TRANSACTION WITH CONSISTENT SNAPSHOT syntax. Additional changes: a) cleanup: - DBerror calls exit() so some code was unneeded - no need to call COMMIT at end, leave disconnection do the job - mysql_query_with_error_report() b) requirements I had heard from colleagues: - --master-data now requires an argument, to comment out ("--") the CHANGE MASTER or not (commenting had been asked for point-in-time recovery when replication is not necessary). - --first-slave is renamed to --lock-all-tables c) more sensible behaviours (has been discussed internally): - if used with --master-data, --flush-logs is probably intended to get a flush synchronous with the dump, not one random flush per dumped db. - disabled automatic reconnection as, at least, SQL_MODE would be lost (and also, depending on options, LOCK TABLES, BEGIN, FLUSH TABLES WITH READ LOCK). include/mysqld_error.h: an error if START TRANSACTION WITH CONSISTENT SNAPSHOT is called and there is no consistent-read capable storage engine (idea ((C) PeterG) is that it's a bit like CREATE TABLE ENGINE=InnoDB when there is no support for InnoDB). sql/handler.cc: new ha_start_consistent_snapshot(), which, inside an existing transaction, starts a consistent read (offers an alternative to SELECTing any InnoDB table). Does something only for InnoDB. Warning if no suitable engine supported. sql/handler.h: declarations sql/lex.h: symbols for lex sql/share/czech/errmsg.txt: new message sql/share/danish/errmsg.txt: new message sql/share/dutch/errmsg.txt: new message sql/share/english/errmsg.txt: new message sql/share/estonian/errmsg.txt: new message sql/share/french/errmsg.txt: new message sql/share/german/errmsg.txt: new message sql/share/greek/errmsg.txt: new message sql/share/hungarian/errmsg.txt: new message sql/share/italian/errmsg.txt: new message sql/share/japanese/errmsg.txt: new message sql/share/korean/errmsg.txt: new message sql/share/norwegian-ny/errmsg.txt: new message sql/share/norwegian/errmsg.txt: new message sql/share/polish/errmsg.txt: new message sql/share/portuguese/errmsg.txt: new message sql/share/romanian/errmsg.txt: new message sql/share/russian/errmsg.txt: new message sql/share/serbian/errmsg.txt: new message sql/share/slovak/errmsg.txt: new message sql/share/spanish/errmsg.txt: new message sql/share/swedish/errmsg.txt: new message sql/share/ukrainian/errmsg.txt: new message sql/sql_lex.h: new option in lex (transaction options) sql/sql_parse.cc: warning comment (never make UNLOCK TABLES commit a transaction, please); support for starting consistent snapshot. sql/sql_yacc.yy: new clause WITH CONSISTENT SNAPSHOT (syntax ok'd by PeterG) for START TRANSACTION. --- sql/handler.cc | 18 ++++++++++++++++++ sql/handler.h | 5 +++-- sql/lex.h | 2 ++ sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sql_lex.h | 2 +- sql/sql_parse.cc | 10 +++++++++- sql/sql_yacc.yy | 21 ++++++++++++++++++--- 29 files changed, 74 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index cb88ab463d8..0c12579cbfd 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -771,6 +771,24 @@ int ha_savepoint(THD *thd, char *savepoint_name) DBUG_RETURN(error); } + +int ha_start_consistent_snapshot(THD *thd) +{ +#ifdef HAVE_INNOBASE_DB + if ((have_innodb == SHOW_OPTION_YES) && + !innobase_start_trx_and_assign_read_view(thd)) + return 0; +#endif + /* + Same idea as when one wants to CREATE TABLE in one engine which does not + exist: + */ + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_NO_CONS_READ_ENGINE, ER(ER_NO_CONS_READ_ENGINE)); + return 0; +} + + bool ha_flush_logs() { bool result=0; diff --git a/sql/handler.h b/sql/handler.h index a7ce4e708fd..fa19f136abf 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -138,6 +138,8 @@ #define HA_CACHE_TBL_ASKTRANSACT 2 #define HA_CACHE_TBL_TRANSACT 4 +/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */ +#define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1 enum db_type { @@ -567,5 +569,4 @@ int ha_discover(THD* thd, const char* dbname, const char* name, int ha_find_files(THD *thd,const char *db,const char *path, const char *wild, bool dir,List* files); int ha_table_exists(THD* thd, const char* db, const char* name); - - +int ha_start_consistent_snapshot(THD *thd); diff --git a/sql/lex.h b/sql/lex.h index c64a7069c32..325d052de90 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -114,6 +114,7 @@ static SYMBOL symbols[] = { { "COMMITTED", SYM(COMMITTED_SYM)}, { "COMPRESSED", SYM(COMPRESSED_SYM)}, { "CONCURRENT", SYM(CONCURRENT)}, + { "CONSISTENT", SYM(CONSISTENT_SYM)}, { "CONSTRAINT", SYM(CONSTRAINT)}, { "CONVERT", SYM(CONVERT_SYM)}, { "CREATE", SYM(CREATE)}, @@ -382,6 +383,7 @@ static SYMBOL symbols[] = { { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, + { "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SMALLINT", SYM(SMALLINT)}, { "SOME", SYM(ANY_SYM)}, { "SONAME", SYM(UDF_SONAME_SYM)}, diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 022a624c921..d352a6e82f7 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -331,3 +331,4 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 18ebe5712f8..e84ee22d5cf 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 54377b5949a..d9d33c3bf59 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -331,3 +331,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 8ede3f61a0b..fd43a2c10c5 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -319,3 +319,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 5aab524e0d9..ae4d5279f35 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin7 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 355e784b156..5217133274b 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -319,3 +319,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 03e838dd805..15f98d36e87 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -332,3 +332,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 06f31a79a73..fae5c508320 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -319,3 +319,4 @@ character-set=greek "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index af10c33ee2d..6f83de7a64d 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index cd66f15db5f..7df71e92fc4 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -319,3 +319,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index eaab58d8403..9fc2ead10d6 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -323,3 +323,4 @@ character-set=ujis "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 1cff50432e9..4e40ffc6264 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -319,3 +319,4 @@ character-set=euckr "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 27f7a18f029..d78c59357f1 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -321,3 +321,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 772f30e5d94..d0a282c444d 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -321,3 +321,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 634a4d93f42..de812697482 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index c79c346008e..262c472a4fa 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -321,3 +321,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 7cb0427dc3f..377ebfbf698 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index df354d5797f..4edfd39c836 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -324,3 +324,4 @@ character-set=koi8r "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 45b56c8269c..e18fa6d2811 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -312,3 +312,4 @@ character-set=cp1250 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 12c3eb2b6af..d935439a1ba 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -327,3 +327,4 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index bd2439c44a6..97fb1bf0be5 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -323,3 +323,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index da75e4fcede..8de68600509 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -319,3 +319,4 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index a19cf946cb1..cf44fea6553 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -325,3 +325,4 @@ character-set=koi8u "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" +"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 268198f74a2..90c020b3e93 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -613,7 +613,7 @@ typedef struct st_lex uint uint_geom_type; uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; - uint slave_thd_opt; + uint slave_thd_opt, start_transaction_opt; uint8 describe; bool drop_if_exists, drop_temporary, local_file, one_shot_set; bool in_comment, ignore_space, verbose, no_write_to_binlog; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f5b9bc0638f..d58fe027acf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3076,6 +3076,12 @@ purposes internal to the MySQL server", MYF(0)); } case SQLCOM_UNLOCK_TABLES: + /* + It is critical for mysqldump --single-transaction --master-data that + UNLOCK TABLES does not implicitely commit a connection which has only + done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes + false, mysqldump will not work. + */ unlock_locked_tables(thd); if (thd->options & OPTION_TABLE_LOCK) { @@ -3462,7 +3468,9 @@ purposes internal to the MySQL server", MYF(0)); thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) | OPTION_BEGIN); thd->server_status|= SERVER_STATUS_IN_TRANS; - send_ok(thd); + if (!(lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT) || + !(res= ha_start_consistent_snapshot(thd))) + send_ok(thd); } break; case SQLCOM_COMMIT: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4538cb6e6ac..1ef91bcb257 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -131,6 +131,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CLIENT_SYM %token COMMENT_SYM %token COMMIT_SYM +%token CONSISTENT_SYM %token COUNT_SYM %token CREATE %token CROSS @@ -165,6 +166,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SELECT_SYM %token SHOW %token SLAVE +%token SNAPSHOT_SYM %token SQL_THREAD %token START_SYM %token STD_SYM @@ -618,6 +620,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options spatial_type union_option + start_transaction_opts %type ULONG_NUM raid_types merge_insert_types @@ -2095,10 +2098,20 @@ slave: start: - START_SYM TRANSACTION_SYM { Lex->sql_command = SQLCOM_BEGIN;} - {} + START_SYM TRANSACTION_SYM start_transaction_opts + { + Lex->sql_command = SQLCOM_BEGIN; + Lex->start_transaction_opt= $3; + } ; +start_transaction_opts: + /*empty*/ { $$ = 0; } + | WITH CONSISTENT_SYM SNAPSHOT_SYM + { + $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT; + } + slave_thread_opts: { Lex->slave_thd_opt= 0; } slave_thread_opt_list @@ -5122,6 +5135,7 @@ keyword: | COMMIT_SYM {} | COMPRESSED_SYM {} | CONCURRENT {} + | CONSISTENT_SYM {} | CUBE_SYM {} | DATA_SYM {} | DATETIME {} @@ -5262,6 +5276,7 @@ keyword: | SHARE_SYM {} | SHUTDOWN {} | SLAVE {} + | SNAPSHOT_SYM {} | SOUNDS_SYM {} | SQL_CACHE_SYM {} | SQL_BUFFER_RESULT {} @@ -5888,7 +5903,7 @@ grant_option: ; begin: - BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work {} + BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN; Lex->start_transaction_opt= 0;} opt_work {} ; opt_work: -- cgit v1.2.1 From c2e3f7cf86ee257b7c95119580fc5bf52c6a5465 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 18:53:16 +0000 Subject: Bug#6469 - REVOKE ALL synonymy bug --- sql/sql_yacc.yy | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 94c0fe3cf0c..2c1416e1bfd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5612,7 +5612,7 @@ revoke_command: grant_privileges ON opt_table FROM user_list {} | - ALL PRIVILEGES ',' GRANT OPTION FROM user_list + ALL opt_privileges ',' GRANT OPTION FROM user_list { Lex->sql_command = SQLCOM_REVOKE_ALL; } @@ -5638,10 +5638,14 @@ grant: grant_privileges: grant_privilege_list {} - | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;} - | ALL { Lex->grant = GLOBAL_ACLS;} + | ALL opt_privileges { Lex->grant = GLOBAL_ACLS;} ; +opt_privileges: + /* empty */ + | PRIVILEGES + ; + grant_privilege_list: grant_privilege | grant_privilege_list ',' grant_privilege; -- cgit v1.2.1 From 5205078ef93edb0b9752285a98aa3616057aad35 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 00:36:18 +0200 Subject: Added possibility to detect if libmysqld is restarted (Needed to check if memory allocated with mysql_once_init() has been freed) include/my_sys.h: Added possibility to detect if libmysqld is restarted mysys/my_init.c: Added possibility to detect if libmysqld is restarted sql/handler.cc: Detect if libmysqld is restarted Simple optimization of ha_known_exts() --- sql/handler.cc | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index 2c274c7989e..34a903cf2c0 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -110,6 +110,7 @@ TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", tx_isolation_names, NULL}; static TYPELIB known_extensions= {0,"known_exts", NULL, NULL}; +uint known_extensions_id= 0; enum db_type ha_resolve_by_name(const char *name, uint namelen) { @@ -1635,6 +1636,7 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key, return error; } + /* Returns a list of all known extensions. @@ -1643,20 +1645,24 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key, NOTES No mutexes, worst case race is a minor surplus memory allocation + We have to recreate the extension map if mysqld is restarted (for example + within libmysqld) RETURN VALUE pointer pointer to TYPELIB structure */ + TYPELIB *ha_known_exts(void) { - if (!known_extensions.type_names) + if (!known_extensions.type_names || mysys_usage_id != known_extensions_id) { show_table_type_st *types; List found_exts; List_iterator_fast it(found_exts); - const char *e, **ext; - - found_exts.push_back(".db"); + const char **ext, *old_ext; + + known_extensions_id= mysys_usage_id; + found_exts.push_back((char*) ".db"); for (types= sys_table_types; types->type; types++) { if (*types->value == SHOW_OPTION_YES) @@ -1664,28 +1670,30 @@ TYPELIB *ha_known_exts(void) handler *file= get_new_handler(0,(enum db_type) types->db_type); for (ext= file->bas_ext(); *ext; ext++) { - while (e=it++) - if (e == *ext) + while ((old_ext= it++)) + { + if (!strcmp(old_ext, *ext)) break; - - if (!e) - found_exts.push_back((char *)*ext); + } + if (!old_ext) + found_exts.push_back((char *) *ext); it.rewind(); } delete file; } } - ext= (const char **)my_once_alloc(sizeof(char *)* - (found_exts.elements+1), MYF(MY_WME)); + ext= (const char **) my_once_alloc(sizeof(char *)* + (found_exts.elements+1), + MYF(MY_WME | MY_FAE)); DBUG_ASSERT(ext); - for (uint i=0; e=it++; i++) - ext[i]= e; - ext[found_exts.elements]= 0; - known_extensions.count= found_exts.elements; known_extensions.type_names= ext; + + while ((old_ext= it++)) + *ext++= old_ext; + *ext= 0; } return &known_extensions; } -- cgit v1.2.1 From b6eb77f73d09c5feb249b6622db461c47afb7c05 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 00:00:17 +0100 Subject: no new message in 4.1 (causes merge issues with 5.0). Using ER_UNKNOW_ERROR and hardcoded message string instead. include/mysqld_error.h: no new message in 4.1 (causes merge issues with 5.0) sql/handler.cc: no new message in 4.1 (causes merge issues with 5.0) sql/share/czech/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/danish/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/dutch/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/english/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/estonian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/french/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/german/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/greek/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/hungarian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/italian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/japanese/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/korean/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/norwegian-ny/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/norwegian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/polish/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/portuguese/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/romanian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/russian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/serbian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/slovak/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/spanish/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/swedish/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) sql/share/ukrainian/errmsg.txt: no new message in 4.1 (causes merge issues with 5.0) --- sql/handler.cc | 5 +++-- sql/share/czech/errmsg.txt | 1 - sql/share/danish/errmsg.txt | 1 - sql/share/dutch/errmsg.txt | 1 - sql/share/english/errmsg.txt | 1 - sql/share/estonian/errmsg.txt | 1 - sql/share/french/errmsg.txt | 1 - sql/share/german/errmsg.txt | 1 - sql/share/greek/errmsg.txt | 1 - sql/share/hungarian/errmsg.txt | 1 - sql/share/italian/errmsg.txt | 1 - sql/share/japanese/errmsg.txt | 1 - sql/share/korean/errmsg.txt | 1 - sql/share/norwegian-ny/errmsg.txt | 1 - sql/share/norwegian/errmsg.txt | 1 - sql/share/polish/errmsg.txt | 1 - sql/share/portuguese/errmsg.txt | 1 - sql/share/romanian/errmsg.txt | 1 - sql/share/russian/errmsg.txt | 1 - sql/share/serbian/errmsg.txt | 1 - sql/share/slovak/errmsg.txt | 1 - sql/share/spanish/errmsg.txt | 1 - sql/share/swedish/errmsg.txt | 1 - sql/share/ukrainian/errmsg.txt | 1 - 24 files changed, 3 insertions(+), 25 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index 32f5ad6ff1d..c1a105a4633 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -785,8 +785,9 @@ int ha_start_consistent_snapshot(THD *thd) Same idea as when one wants to CREATE TABLE in one engine which does not exist: */ - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_NO_CONS_READ_ENGINE, ER(ER_NO_CONS_READ_ENGINE)); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, + "This MySQL server does not support any " + "consistent-read capable storage engine"); return 0; } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index d352a6e82f7..022a624c921 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -331,4 +331,3 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index e84ee22d5cf..18ebe5712f8 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -322,4 +322,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index d9d33c3bf59..54377b5949a 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -331,4 +331,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index fd43a2c10c5..8ede3f61a0b 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -319,4 +319,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index ae4d5279f35..5aab524e0d9 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -324,4 +324,3 @@ character-set=latin7 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 5217133274b..355e784b156 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -319,4 +319,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 15f98d36e87..03e838dd805 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -332,4 +332,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index fae5c508320..06f31a79a73 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -319,4 +319,3 @@ character-set=greek "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 6f83de7a64d..af10c33ee2d 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -324,4 +324,3 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 7df71e92fc4..cd66f15db5f 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -319,4 +319,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 9fc2ead10d6..eaab58d8403 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -323,4 +323,3 @@ character-set=ujis "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 4e40ffc6264..1cff50432e9 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -319,4 +319,3 @@ character-set=euckr "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index d78c59357f1..27f7a18f029 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -321,4 +321,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index d0a282c444d..772f30e5d94 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -321,4 +321,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index de812697482..634a4d93f42 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -324,4 +324,3 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 262c472a4fa..c79c346008e 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -321,4 +321,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 377ebfbf698..7cb0427dc3f 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -324,4 +324,3 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 4edfd39c836..df354d5797f 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -324,4 +324,3 @@ character-set=koi8r "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index e18fa6d2811..45b56c8269c 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -312,4 +312,3 @@ character-set=cp1250 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index d935439a1ba..12c3eb2b6af 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -327,4 +327,3 @@ character-set=latin2 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 97fb1bf0be5..bd2439c44a6 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -323,4 +323,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 8de68600509..da75e4fcede 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -319,4 +319,3 @@ character-set=latin1 "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index cf44fea6553..a19cf946cb1 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -325,4 +325,3 @@ character-set=koi8u "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" "Conflicting declarations: '%s%s' and '%s%s'" -"This MySQL server does not support any consistent-read capable storage engine" -- cgit v1.2.1 From 02d8fa295202649863fef5f9d6eadde8dee51a06 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 10:50:46 +0400 Subject: Added ending ';' for the start_transaction_opts: --- sql/sql_yacc.yy | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1852101fcfb..7fa6549686b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2111,6 +2111,7 @@ start_transaction_opts: { $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT; } + ; slave_thread_opts: { Lex->slave_thd_opt= 0; } -- cgit v1.2.1 From b203c6c806302868d62eebaeb36dd831eb2a2e2a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 10:09:50 +0200 Subject: WL#1972 - manual merge with latest bk source sql/sql_select.cc: manual merge with latest bk source --- sql/sql_select.cc | 474 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 277 insertions(+), 197 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 178d36faa2a..924b74e2e6e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -91,7 +91,7 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables, uint select_options, const char *info, Item *having, Procedure *proc, SELECT_LEX_UNIT *unit); -static COND *build_equal_items(COND *cond, +static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited, List *join_list, COND_EQUAL **cond_equal_ref); @@ -101,6 +101,7 @@ static COND* substitute_for_best_equal_field(COND *cond, static COND *simplify_joins(JOIN *join, List *join_list, COND *conds, bool top); static COND *optimize_cond(JOIN *join, COND *conds, + List *join_list, Item::cond_result *cond_value); static bool resolve_nested_join (TABLE_LIST *table); static COND *remove_eq_conds(THD *thd, COND *cond, @@ -191,6 +192,7 @@ static void init_tmptable_sum_functions(Item_sum **func); static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table); static void copy_sum_funcs(Item_sum **func_ptr); static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); +static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr); static bool init_sum_functions(Item_sum **func, Item_sum **end); static bool update_sum_func(Item_sum **func); static void select_describe(JOIN *join, bool need_tmp_table,bool need_order, @@ -228,16 +230,11 @@ int handle_select(THD *thd, LEX *lex, select_result *result) select_lex->options | thd->options, result, unit, select_lex); } - - /* Don't set res if it's -1 as we may want this later */ DBUG_PRINT("info",("res: %d report_error: %d", res, thd->net.report_error)); - if (thd->net.report_error) - res= 1; - if (unlikely(res)) + if (thd->net.report_error || res < 0) { - if (res > 0) - result->send_error(0, NullS); + result->send_error(0, NullS); result->abort(); res= 1; // Error sent to client } @@ -333,7 +330,7 @@ JOIN::prepare(Item ***rref_pointer_array, if (having_fix_rc || thd->net.report_error) DBUG_RETURN(-1); /* purecov: inspected */ if (having->with_sum_func) - having->split_sum_func(ref_pointer_array, all_fields); + having->split_sum_func(thd, ref_pointer_array, all_fields); } if (!thd->lex->view_prepare_mode) @@ -558,17 +555,7 @@ JOIN::optimize() thd->restore_backup_item_arena(arena, &backup); } - /* - Build all multiple equality predicates and eliminate equality - predicates that can be inferred from these multiple equalities. - For each reference of a field included into a multiple equality - that occurs in a function set a pointer to the multiple equality - predicate. Substitute a constant instead of this field if the - multiple equality contains a constant. - */ - conds= build_equal_items(conds, NULL, join_list, &cond_equal); - - conds= optimize_cond(this, conds,&cond_value); + conds= optimize_cond(this, conds, join_list, &cond_value); if (thd->net.report_error) { error= 1; @@ -686,6 +673,7 @@ JOIN::optimize() { conds= substitute_for_best_equal_field(conds, cond_equal, map2table); conds->update_used_tables(); + DBUG_EXECUTE("where", print_where(conds, "after substitute_best_equal");); } /* Permorm the the optimization on fields evaluation mentioned above @@ -1003,13 +991,15 @@ JOIN::optimize() if (create_sort_index(thd, this, group_list, HA_POS_ERROR, HA_POS_ERROR) || alloc_group_fields(this, group_list) || - make_sum_func_list(all_fields, fields_list, 1)) + make_sum_func_list(all_fields, fields_list, 1) || + setup_sum_funcs(thd, sum_funcs)) DBUG_RETURN(1); group_list=0; } else { - if (make_sum_func_list(all_fields, fields_list, 0)) + if (make_sum_func_list(all_fields, fields_list, 0) || + setup_sum_funcs(thd, sum_funcs)) DBUG_RETURN(1); if (!group_list && ! exec_tmp_table1->distinct && order && simple_order) { @@ -1385,6 +1375,7 @@ JOIN::exec() } if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, 1, TRUE) || + setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) || (tmp_error= do_select(curr_join, (List *) 0, curr_tmp_table, 0))) { @@ -1472,7 +1463,9 @@ JOIN::exec() set_items_ref_array(items3); if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, - 1, TRUE) || thd->is_fatal_error) + 1, TRUE) || + setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) || + thd->is_fatal_error) DBUG_VOID_RETURN; } if (curr_join->group_list || curr_join->order) @@ -1665,9 +1658,13 @@ Cursor::init_from_thd(THD *thd) /* We need to save and reset thd->mem_root, otherwise it'll be freed later in mysql_parse. + + We can't just change the thd->mem_root here as we want to keep the things + that is already allocated in thd->mem_root for Cursor::fetch() */ - mem_root= thd->mem_root; - init_sql_alloc(&thd->mem_root, + main_mem_root= *thd->mem_root; + /* Allocate new memory root for thd */ + init_sql_alloc(thd->mem_root, thd->variables.query_alloc_block_size, thd->variables.query_prealloc_size); @@ -1681,7 +1678,7 @@ Cursor::init_from_thd(THD *thd) open_tables= thd->open_tables; lock= thd->lock; query_id= thd->query_id; - free_list= thd->free_list; + free_list= thd->free_list; reset_thd(thd); /* XXX: thd->locked_tables is not changed. @@ -1696,8 +1693,6 @@ Cursor::init_from_thd(THD *thd) void Cursor::init_thd(THD *thd) { - thd->mem_root= mem_root; - DBUG_ASSERT(thd->derived_tables == 0); thd->derived_tables= derived_tables; @@ -1707,7 +1702,6 @@ Cursor::init_thd(THD *thd) DBUG_ASSERT(thd->lock== 0); thd->lock= lock; thd->query_id= query_id; - thd->free_list= free_list; } @@ -1725,11 +1719,10 @@ int Cursor::open(JOIN *join_arg) { join= join_arg; - THD *thd= join->thd; - /* First non-constant table */ JOIN_TAB *join_tab= join->join_tab + join->const_tables; + DBUG_ENTER("Cursor::open"); /* Send fields description to the client; server_status is sent @@ -1751,7 +1744,9 @@ Cursor::open(JOIN *join_arg) join->fetch_limit= join->unit->offset_limit_cnt; /* Disable JOIN CACHE as it is not working with cursors yet */ - for (JOIN_TAB *tab= join_tab; tab != join->join_tab + join->tables - 1; ++tab) + for (JOIN_TAB *tab= join_tab; + tab != join->join_tab + join->tables - 1; + tab++) { if (tab->next_select == sub_select_cache) tab->next_select= sub_select; @@ -1765,7 +1760,7 @@ Cursor::open(JOIN *join_arg) */ DBUG_ASSERT(join_tab->table->null_row == 0); - return join_tab->read_first_record(join_tab); + DBUG_RETURN(join_tab->read_first_record(join_tab)); } @@ -1784,13 +1779,15 @@ int Cursor::fetch(ulong num_rows) { THD *thd= join->thd; - JOIN_TAB *join_tab= join->join_tab + join->const_tables;; + JOIN_TAB *join_tab= join->join_tab + join->const_tables; COND *on_expr= *join_tab->on_expr_ref; COND *select_cond= join_tab->select_cond; READ_RECORD *info= &join_tab->read_record; - int error= 0; + /* save references to memory, allocated during fetch */ + thd->set_n_backup_item_arena(this, &thd->stmt_backup); + join->fetch_limit+= num_rows; /* @@ -1855,53 +1852,37 @@ Cursor::fetch(ulong num_rows) if (thd->net.report_error) error= -1; - switch (error) { - /* Fetch limit worked, possibly more rows are there */ - case -4: + if (error == -3) /* LIMIT clause worked */ + error= 0; + +#ifdef USING_TRANSACTIONS if (thd->transaction.all.innobase_tid) ha_release_temporary_latches(thd); +#endif + + thd->restore_backup_item_arena(this, &thd->stmt_backup); + if (error == -4) + { + /* Fetch limit worked, possibly more rows are there */ thd->server_status|= SERVER_STATUS_CURSOR_EXISTS; ::send_eof(thd); thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; - /* save references to memory, allocated during fetch */ - mem_root= thd->mem_root; - free_list= thd->free_list; - break; - /* Limit clause worked: this is the same as 'no more rows' */ - case -3: /* LIMIT clause worked */ - error= 0; - /* fallthrough */ - case 0: /* No more rows */ - if (thd->transaction.all.innobase_tid) - ha_release_temporary_latches(thd); - close(); - thd->server_status|= SERVER_STATUS_LAST_ROW_SENT; - ::send_eof(thd); - thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT; - join= 0; - unit= 0; - free_items(thd->free_list); - thd->free_list= free_list= 0; - /* - Must be last, as some memory might be allocated for free purposes, - like in free_tmp_table() (TODO: fix this issue) - */ - mem_root= thd->mem_root; - free_root(&mem_root, MYF(0)); - break; - default: + } + else + { close(); - join= 0; - unit= 0; - free_items(thd->free_list); - thd->free_list= free_list= 0; - /* - Must be last, as some memory might be allocated for free purposes, - like in free_tmp_table() (TODO: fix this issue) - */ - mem_root= thd->mem_root; - free_root(&mem_root, MYF(0)); - break; + if (error == 0) + { + thd->server_status|= SERVER_STATUS_LAST_ROW_SENT; + ::send_eof(thd); + thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT; + } + else + send_error(thd, ER_OUT_OF_RESOURCES); + /* free cursor memory */ + free_items(free_list); + free_list= 0; + free_root(&main_mem_root, MYF(0)); } return error; } @@ -1939,6 +1920,8 @@ Cursor::close() thd->derived_tables= tmp_derived_tables; thd->lock= tmp_lock; } + join= 0; + unit= 0; } @@ -1951,7 +1934,7 @@ Cursor::~Cursor() Must be last, as some memory might be allocated for free purposes, like in free_tmp_table() (TODO: fix this issue) */ - free_root(&mem_root, MYF(0)); + free_root(&main_mem_root, MYF(0)); } /*********************************************************************/ @@ -5030,7 +5013,7 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab) { tmp= new Item_func_trig_cond(tmp, &tab->found); } - if (!tmp) + if (tmp) tmp->quick_fix_field(); return tmp; } @@ -5304,8 +5287,17 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) /* Join with outer join condition */ COND *orig_cond=sel->cond; sel->cond= and_conds(sel->cond, *tab->on_expr_ref); + + /* + We can't call sel->cond->fix_fields, + as it will break tab->on_expr if it's AND condition + (fix_fields currently removes extra AND/OR levels). + Yet attributes of the just built condition are not needed. + Thus we call sel->cond->quick_fix_field for safety. + */ if (sel->cond && !sel->cond->fixed) - sel->cond->fix_fields(join->thd, 0, &sel->cond); + sel->cond->quick_fix_field(); + if (sel->test_quick_select(join->thd, tab->keys, used_tables & ~ current_map, (join->select_options & @@ -6030,7 +6022,7 @@ template class List_iterator; find_item_equal() cond_equal multiple equalities to search in field field to look for - inherited_fl :out set up to TRUE iff multiple equality is found + inherited_fl :out set up to TRUE if multiple equality is found on upper levels (not on current level of cond_equal) DESCRIPTION @@ -6448,12 +6440,14 @@ static COND *build_equal_items_for_cond(COND *cond, return cond; } + /* Build multiple equalities for a condition and all on expressions that inherit these multiple equalities SYNOPSIS build_equal_items() + thd Thread handler cond condition to build the multiple equalities for inherited path to all inherited multiple equality items join_list list of join tables to which the condition refers to @@ -6505,7 +6499,7 @@ static COND *build_equal_items_for_cond(COND *cond, pointer to the transformed condition containing multiple equalities */ -static COND *build_equal_items(COND *cond, +static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited, List *join_list, COND_EQUAL **cond_equal_ref) @@ -6542,12 +6536,13 @@ static COND *build_equal_items(COND *cond, { if (table->on_expr) { + Item *expr; List *join_list= table->nested_join ? &table->nested_join->join_list : NULL; - table->on_expr= build_equal_items(table->on_expr, - inherited, - join_list, - &table->cond_equal); + expr= build_equal_items(thd, table->on_expr, inherited, join_list, + &table->cond_equal); + if (expr != table->on_expr) + thd->change_item_tree(&table->on_expr, expr); } } } @@ -6555,6 +6550,7 @@ static COND *build_equal_items(COND *cond, return cond; } + /* Compare field items by table order in the execution plan @@ -6649,10 +6645,7 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, List eq_list; Item_func_eq *eq_item= 0; if (((Item *) item_equal)->const_item() && !item_equal->val_int()) - { - cond= new Item_int((char*) "FALSE",0,1); - return cond; - } + return new Item_int((longlong) 0,1); Item *item_const= item_equal->get_const(); Item_equal_iterator it(*item_equal); Item *head; @@ -6695,9 +6688,14 @@ static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels, } if (!cond && !eq_list.head()) + { + if (!eq_item) + return new Item_int((longlong) 1,1); return eq_item; + } - eq_list.push_back(eq_item); + if (eq_item) + eq_list.push_back(eq_item); if (!cond) cond= new Item_cond_and(eq_list); else @@ -6799,14 +6797,16 @@ static COND* substitute_for_best_equal_field(COND *cond, return cond; } + /* change field = field to field = const for each found field = const in the and_level */ static void -change_cond_ref_to_const(I_List *save_list,Item *and_father, - Item *cond, Item *field, Item *value) +change_cond_ref_to_const(THD *thd, I_List *save_list, + Item *and_father, Item *cond, + Item *field, Item *value) { if (cond->type() == Item::COND_ITEM) { @@ -6815,7 +6815,7 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, List_iterator li(*((Item_cond*) cond)->argument_list()); Item *item; while ((item=li++)) - change_cond_ref_to_const(save_list,and_level ? cond : item, item, + change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item, field, value); return; } @@ -6823,8 +6823,9 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, return; // Not a boolean function Item_bool_func2 *func= (Item_bool_func2*) cond; - Item *left_item= func->arguments()[0]; - Item *right_item= func->arguments()[1]; + Item **args= func->arguments(); + Item *left_item= args[0]; + Item *right_item= args[1]; Item_func::Functype functype= func->functype(); if (right_item->eq(field,0) && left_item != value && @@ -6835,7 +6836,7 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, Item *tmp=value->new_item(); if (tmp) { - func->arguments()[1] = tmp; + thd->change_item_tree(args + 1, tmp); func->update_used_tables(); if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) && and_father != cond && !left_item->const_item()) @@ -6856,13 +6857,14 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, Item *tmp=value->new_item(); if (tmp) { - func->arguments()[0] = value = tmp; + thd->change_item_tree(args, tmp); + value= tmp; func->update_used_tables(); if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) && and_father != cond && !right_item->const_item()) { - func->arguments()[0] = func->arguments()[1]; // For easy check - func->arguments()[1] = value; + args[0]= args[1]; // For easy check + thd->change_item_tree(args + 1, value); cond->marker=1; COND_CMP *tmp2; if ((tmp2=new COND_CMP(and_father,func))) @@ -6908,8 +6910,8 @@ static Item *remove_additional_cond(Item* conds) } static void -propagate_cond_constants(I_List *save_list,COND *and_father, - COND *cond) +propagate_cond_constants(THD *thd, I_List *save_list, + COND *and_father, COND *cond) { if (cond->type() == Item::COND_ITEM) { @@ -6920,18 +6922,19 @@ propagate_cond_constants(I_List *save_list,COND *and_father, I_List save; while ((item=li++)) { - propagate_cond_constants(&save,and_level ? cond : item, item); + propagate_cond_constants(thd, &save,and_level ? cond : item, item); } if (and_level) { // Handle other found items I_List_iterator cond_itr(save); COND_CMP *cond_cmp; while ((cond_cmp=cond_itr++)) - if (!cond_cmp->cmp_func->arguments()[0]->const_item()) - change_cond_ref_to_const(&save,cond_cmp->and_level, - cond_cmp->and_level, - cond_cmp->cmp_func->arguments()[0], - cond_cmp->cmp_func->arguments()[1]); + { + Item **args= cond_cmp->cmp_func->arguments(); + if (!args[0]->const_item()) + change_cond_ref_to_const(thd, &save,cond_cmp->and_level, + cond_cmp->and_level, args[0], args[1]); + } } } else if (and_father != cond && !cond->marker) // In a AND group @@ -6941,29 +6944,25 @@ propagate_cond_constants(I_List *save_list,COND *and_father, ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)) { Item_func_eq *func=(Item_func_eq*) cond; - bool left_const= func->arguments()[0]->const_item(); - bool right_const=func->arguments()[1]->const_item(); + Item **args= func->arguments(); + bool left_const= args[0]->const_item(); + bool right_const= args[1]->const_item(); if (!(left_const && right_const) && - (func->arguments()[0]->result_type() == - (func->arguments()[1]->result_type()))) + args[0]->result_type() == args[1]->result_type()) { if (right_const) { - func->arguments()[1]=resolve_const_item(func->arguments()[1], - func->arguments()[0]); + resolve_const_item(thd, &args[1], args[0]); func->update_used_tables(); - change_cond_ref_to_const(save_list,and_father,and_father, - func->arguments()[0], - func->arguments()[1]); + change_cond_ref_to_const(thd, save_list, and_father, and_father, + args[0], args[1]); } else if (left_const) { - func->arguments()[0]=resolve_const_item(func->arguments()[0], - func->arguments()[1]); + resolve_const_item(thd, &args[0], args[1]); func->update_used_tables(); - change_cond_ref_to_const(save_list,and_father,and_father, - func->arguments()[1], - func->arguments()[0]); + change_cond_ref_to_const(thd, save_list, and_father, and_father, + args[1], args[0]); } } } @@ -7091,6 +7090,7 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) */ if (table->on_expr) { + Item *expr; /* If an on expression E is attached to the table, check all null rejected predicates in this expression. @@ -7099,8 +7099,9 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) the outer join is converted to an inner join and the corresponding on expression is added to E. */ - table->on_expr= simplify_joins(join, &nested_join->join_list, - table->on_expr, FALSE); + expr= simplify_joins(join, &nested_join->join_list, + table->on_expr, FALSE); + table->on_expr= expr; } nested_join->used_tables= (table_map) 0; nested_join->not_null_tables=(table_map) 0; @@ -7209,8 +7210,10 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) DBUG_RETURN(conds); } + static COND * -optimize_cond(JOIN *join, COND *conds, Item::cond_result *cond_value) +optimize_cond(JOIN *join, COND *conds, List *join_list, + Item::cond_result *cond_value) { THD *thd= join->thd; SELECT_LEX *select= thd->lex->current_select; @@ -7223,9 +7226,21 @@ optimize_cond(JOIN *join, COND *conds, Item::cond_result *cond_value) } else { + /* + Build all multiple equality predicates and eliminate equality + predicates that can be inferred from these multiple equalities. + For each reference of a field included into a multiple equality + that occurs in a function set a pointer to the multiple equality + predicate. Substitute a constant instead of this field if the + multiple equality contains a constant. + */ DBUG_EXECUTE("where", print_where(conds, "original");); + conds= build_equal_items(join->thd, conds, NULL, join_list, + &join->cond_equal); + DBUG_EXECUTE("where",print_where(conds,"after equal_items");); + /* change field = field to field = const for each found field = const */ - propagate_cond_constants((I_List *) 0,conds,conds); + propagate_cond_constants(thd, (I_List *) 0, conds, conds); /* Remove all instances of item == item Remove all and-levels where CONST item != CONST item @@ -7461,21 +7476,28 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item) the record in the original table. If modify_item is 0 then fill_record() will update the temporary table + convert_blob_length If >0 create a varstring(convert_blob_length) field + instead of blob. RETURN 0 on error new_created field */ -static Field* create_tmp_field_from_field(THD *thd, - Field* org_field, - Item *item, - TABLE *table, - bool modify_item) + +static Field* create_tmp_field_from_field(THD *thd, Field* org_field, + Item *item, TABLE *table, + bool modify_item, + uint convert_blob_length) { Field *new_field; - // The following should always be true - if ((new_field= org_field->new_field(&thd->mem_root,table))) + if (convert_blob_length && org_field->flags & BLOB_FLAG) + new_field= new Field_varstring(convert_blob_length, org_field->maybe_null(), + org_field->field_name, table, + org_field->charset()); + else + new_field= org_field->new_field(thd->mem_root, table); + if (new_field) { if (modify_item) ((Item_field *)item)->result_field= new_field; @@ -7506,16 +7528,16 @@ static Field* create_tmp_field_from_field(THD *thd, the record in the original table. If modify_item is 0 then fill_record() will update the temporary table + convert_blob_length If >0 create a varstring(convert_blob_length) field + instead of blob. RETURN 0 on error new_created field */ -static Field* create_tmp_field_from_item(THD *thd, - Item *item, - TABLE *table, - Item ***copy_func, - bool modify_item) +static Field* create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, + Item ***copy_func, bool modify_item, + uint convert_blob_length) { bool maybe_null=item->maybe_null; Field *new_field; @@ -7532,13 +7554,18 @@ static Field* create_tmp_field_from_item(THD *thd, break; case STRING_RESULT: if (item->max_length > 255) - new_field= new Field_blob(item->max_length, maybe_null, - item->name, table, - item->collation.collation); + { + if (convert_blob_length) + new_field= new Field_varstring(convert_blob_length, maybe_null, + item->name, table, + item->collation.collation); + else + new_field= new Field_blob(item->max_length, maybe_null, item->name, + table, item->collation.collation); + } else - new_field= new Field_string(item->max_length, maybe_null, - item->name, table, - item->collation.collation); + new_field= new Field_string(item->max_length, maybe_null, item->name, + table, item->collation.collation); break; case ROW_RESULT: default: @@ -7575,6 +7602,8 @@ static Field* create_tmp_field_from_item(THD *thd, the record in the original table. If modify_item is 0 then fill_record() will update the temporary table + convert_blob_length If >0 create a varstring(convert_blob_length) field + instead of blob. RETURN 0 on error @@ -7582,8 +7611,8 @@ static Field* create_tmp_field_from_item(THD *thd, */ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, - Item ***copy_func, Field **from_field, - bool group, bool modify_item) + Item ***copy_func, Field **from_field, + bool group, bool modify_item, uint convert_blob_length) { switch (type) { case Item::SUM_FUNC_ITEM: @@ -7618,8 +7647,15 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, item->name,table,item->unsigned_flag); case STRING_RESULT: if (item_sum->max_length > 255) - return new Field_blob(item_sum->max_length,maybe_null, - item->name,table,item->collation.collation); + { + if (convert_blob_length) + return new Field_varstring(convert_blob_length, maybe_null, + item->name, table, + item->collation.collation); + else + return new Field_blob(item_sum->max_length, maybe_null, item->name, + table, item->collation.collation); + } return new Field_string(item_sum->max_length,maybe_null, item->name,table,item->collation.collation); case ROW_RESULT: @@ -7636,8 +7672,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::DEFAULT_VALUE_ITEM: { Item_field *field= (Item_field*) item; - return create_tmp_field_from_field(thd, (*from_field= field->field), - item, table, modify_item); + return create_tmp_field_from_field(thd, (*from_field= field->field), item, + table, modify_item, convert_blob_length); } case Item::FUNC_ITEM: case Item::COND_ITEM: @@ -7652,14 +7688,16 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::REF_ITEM: case Item::NULL_ITEM: case Item::VARBIN_ITEM: - return create_tmp_field_from_item(thd, item, table, - copy_func, modify_item); + return create_tmp_field_from_item(thd, item, table, copy_func, modify_item, + convert_blob_length); case Item::TYPE_HOLDER: { Field *example= ((Item_type_holder *)item)->example(); if (example) - return create_tmp_field_from_field(thd, example, item, table, 0); - return create_tmp_field_from_item(thd, item, table, copy_func, 0); + return create_tmp_field_from_field(thd, example, item, table, 0, + convert_blob_length); + return create_tmp_field_from_item(thd, item, table, copy_func, 0, + convert_blob_length); } default: // Dosen't have to be stored return 0; @@ -7818,12 +7856,14 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, ((Item_sum*) item)->result_field=0; for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++) { - Item *arg= ((Item_sum*) item)->args[i]; + Item **argp= ((Item_sum*) item)->args + i; + Item *arg= *argp; if (!arg->const_item()) { Field *new_field= - create_tmp_field(thd, table,arg,arg->type(),©_func, - tmp_from_field, group != 0,not_all_columns); + create_tmp_field(thd, table, arg, arg->type(), ©_func, + tmp_from_field, group != 0,not_all_columns, + param->convert_blob_length); if (!new_field) goto err; // Should be OOM tmp_from_field++; @@ -7834,7 +7874,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, *blob_field++= new_field; blob_count++; } - ((Item_sum*) item)->args[i]= new Item_field(new_field); + thd->change_item_tree(argp, new Item_field(new_field)); if (!(new_field->flags & NOT_NULL_FLAG)) { null_count++; @@ -7842,7 +7882,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, new_field->maybe_null() is still false, it will be changed below. But we have to setup Item_field correctly */ - ((Item_sum*) item)->args[i]->maybe_null=1; + (*argp)->maybe_null=1; } } } @@ -7859,9 +7899,10 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, We here distinguish between UNION and multi-table-updates by the fact that in the later case group is set to the row pointer. */ - Field *new_field=create_tmp_field(thd, table, item,type, ©_func, - tmp_from_field, group != 0, - not_all_columns || group !=0); + Field *new_field= create_tmp_field(thd, table, item, type, ©_func, + tmp_from_field, group != 0, + not_all_columns || group !=0, + param->convert_blob_length); if (!new_field) { if (thd->is_fatal_error) @@ -8058,7 +8099,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, if (!using_unique_constraint) { group->buff=(char*) group_buff; - if (!(group->field=field->new_field(&thd->mem_root,table))) + if (!(group->field=field->new_field(thd->mem_root,table))) goto err; /* purecov: inspected */ if (maybe_null) { @@ -8569,7 +8610,7 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) DBUG_PRINT("error",("Error: do_select() failed")); } #endif - DBUG_RETURN(error || join->thd->net.report_error); + DBUG_RETURN(join->thd->net.report_error ? -1 : error); } @@ -9050,6 +9091,7 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos) { table->key_read=1; table->file->extra(HA_EXTRA_KEYREAD); + tab->index= tab->ref.key; } if ((error=join_read_const(tab))) { @@ -10037,10 +10079,23 @@ part_of_refkey(TABLE *table,Field *field) /***************************************************************************** Test if one can use the key to resolve ORDER BY - Returns: 1 if key is ok. - 0 if key can't be used - -1 if reverse key can be used - used_key_parts is set to key parts used if length != 0 + + SYNOPSIS + test_if_order_by_key() + order Sort order + table Table to sort + idx Index to check + used_key_parts Return value for used key parts. + + + NOTES + used_key_parts is set to correct key parts used if return value != 0 + (On other cases, used_key_part may be changed) + + RETURN + 1 key is ok. + 0 Key can't be used + -1 Reverse key can be used *****************************************************************************/ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, @@ -10069,13 +10124,17 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx, DBUG_RETURN(0); /* set flag to 1 if we can use read-next on key, else to -1 */ - flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ? 1 : -1); + flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ? + 1 : -1); if (reverse && flag != reverse) DBUG_RETURN(0); reverse=flag; // Remember if reverse key_part++; } *used_key_parts= (uint) (key_part - table->key_info[idx].key_part); + if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) & + HA_READ_PREV)) + reverse= 0; // Index can't be used DBUG_RETURN(reverse); } @@ -10288,14 +10347,11 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, if (!select->quick->reverse_sorted()) { int quick_type= select->quick->get_type(); - /* here used_key_parts >0 */ - if (!(table->file->index_flags(ref_key,used_key_parts-1, 1) - & HA_READ_PREV) || - quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || + if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) - DBUG_RETURN(0); // Use filesort + DBUG_RETURN(0); // Use filesort /* ORDER BY range_key DESC */ QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick), @@ -10317,9 +10373,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, Use a traversal function that starts by reading the last row with key part (A) and then traverse the index backwards. */ - if (!(table->file->index_flags(ref_key,used_key_parts-1, 1) - & HA_READ_PREV)) - DBUG_RETURN(0); // Use filesort tab->read_first_record= join_read_last_key; tab->read_record.read_record= join_read_prev_same; /* fall through */ @@ -10365,7 +10418,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, if (keys.is_set(nr)) { int flag; - if ((flag=test_if_order_by_key(order, table, nr, ¬_used))) + if ((flag= test_if_order_by_key(order, table, nr, ¬_used))) { if (!no_changes) { @@ -11150,7 +11203,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, ORDER *order, List &fields, List &all_fields, bool is_group_field) { - Item *order_item=*order->item; /* The item from the GROUP/ORDER caluse. */ + Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */ Item::Type order_item_type; Item **select_item; /* The corresponding item from the SELECT clause. */ Field *from_field; /* The corresponding field from the FROM clause. */ @@ -11161,8 +11214,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, if (!count || count > fields.elements) { my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), - MYF(0),order_item->full_name(), - thd->where); + MYF(0), order_item->full_name(), thd->where); return 1; } order->item= ref_pointer_array + count - 1; @@ -11173,8 +11225,9 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, } /* Lookup the current GROUP/ORDER field in the SELECT clause. */ uint counter; + bool unaliased; select_item= find_item_in_list(order_item, fields, &counter, - REPORT_EXCEPT_NOT_FOUND); + REPORT_EXCEPT_NOT_FOUND, &unaliased); if (!select_item) return 1; /* Some error occured. */ @@ -11182,6 +11235,14 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, /* Check whether the resolved field is not ambiguos. */ if (select_item != not_found_item) { + /* + If we have found field not by its alias in select list but by its + original field name, we should additionaly check if we have conflict + for this name (in case if we would perform lookup in all tables). + */ + if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables, order->item)) + return 1; + /* Lookup the current GROUP field in the FROM clause. */ order_item_type= order_item->type(); if (is_group_field && @@ -11215,16 +11276,15 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, } order->in_field_list=0; - Item *it= *order->item; /* - We check it->fixed because Item_func_group_concat can put + We check order_item->fixed because Item_func_group_concat can put arguments for which fix_fields already was called. 'it' reassigned in if condition because fix_field can change it. */ - if (!it->fixed && - (it->fix_fields(thd, tables, order->item) || - (it= *order->item)->check_cols(1) || + if (!order_item->fixed && + (order_item->fix_fields(thd, tables, order->item) || + (order_item= *order->item)->check_cols(1) || thd->is_fatal_error)) return 1; // Wrong field uint el= all_fields.elements; @@ -11234,6 +11294,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, return 0; } + /* Change order to point at item in select list. If item isn't a number and doesn't exits in the select list, add it the the field list. @@ -11344,10 +11405,11 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List &fields, thd->set_query_id=1; // Not really needed, but... uint counter; + bool not_used; for (; new_field ; new_field= new_field->next) { if ((item= find_item_in_list(*new_field->item, fields, &counter, - IGNORE_ERRORS))) + IGNORE_ERRORS, ¬_used))) new_field->item=item; /* Change to shared Item */ else { @@ -11695,7 +11757,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, saved value */ Field *field= item->field; - item->result_field=field->new_field(&thd->mem_root,field->table); + item->result_field=field->new_field(thd->mem_root,field->table); char *tmp=(char*) sql_alloc(field->pack_length()+1); if (!tmp) goto err; @@ -11705,6 +11767,8 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, } } else if ((pos->type() == Item::FUNC_ITEM || + pos->type() == Item::SUBSELECT_ITEM || + pos->type() == Item::CACHE_ITEM || pos->type() == Item::COND_ITEM) && !pos->with_sum_func) { // Save for send fields @@ -11812,9 +11876,6 @@ bool JOIN::alloc_func_list() before_group_by Set to 1 if this is called before GROUP BY handling recompute Set to TRUE if sum_funcs must be recomputed - NOTES - Calls ::setup() for all item_sum objects in field_list - RETURN 0 ok 1 error @@ -11835,12 +11896,7 @@ bool JOIN::make_sum_func_list(List &field_list, List &send_fields, while ((item=it++)) { if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item()) - { *func++= (Item_sum*) item; - /* let COUNT(DISTINCT) create the temporary table */ - if (((Item_sum*) item)->setup(thd)) - DBUG_RETURN(TRUE); - } } if (before_group_by && rollup.state == ROLLUP::STATE_INITED) { @@ -11985,6 +12041,30 @@ change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array, Code for calculating functions ******************************************************************************/ + +/* + Call ::setup for all sum functions + + SYNOPSIS + setup_sum_funcs() + thd thread handler + func_ptr sum function list + + RETURN + FALSE ok + TRUE error +*/ + +static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr) +{ + Item_sum *func; + while ((func= *(func_ptr++))) + if (func->setup(thd)) + return TRUE; + return FALSE; +} + + static void init_tmptable_sum_functions(Item_sum **func_ptr) { @@ -12140,7 +12220,7 @@ bool JOIN::rollup_init() return 1; rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts); ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts); - rollup.item_null= new (&thd->mem_root) Item_null(); + rollup.item_null= new (thd->mem_root) Item_null(); /* Prepare space for field list for the different levels -- cgit v1.2.1 From d2a3420dd363eba298f4544bb58a8b9860477bb5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 12:35:55 +0400 Subject: A fix (bug #6551: UMASK_DIR & UMASK not taken into account (mysqld.cc my_init.c inconsistency)). my_umask and my_umask_dir initialization has been moved to the my_init() func. mysys/my_init.c: A fix (bug #6551: UMASK_DIR & UMASK not taken into account (mysqld.cc my_init.c inconsistency)) sql/mysqld.cc: A fix (bug #6551: UMASK_DIR & UMASK not taken into account (mysqld.cc my_init.c inconsistency)) --- sql/mysqld.cc | 2 -- 1 file changed, 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5622ac50a7b..4b70e8552b5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2305,8 +2305,6 @@ bool init_global_datetime_format(timestamp_type format_type, static int init_common_variables(const char *conf_file_name, int argc, char **argv, const char **groups) { - my_umask=0660; // Default umask for new files - my_umask_dir=0700; // Default umask for new directories umask(((~my_umask) & 0666)); tzset(); // Set tzname -- cgit v1.2.1 From a5585f62d8b8451a5212b0c6f20052b9477ef0b4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 11:16:51 +0200 Subject: WL#1972 - manual merge with latest bk source tree sql/item.cc: manual merge with latest bk source tree --- sql/item.cc | 477 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 347 insertions(+), 130 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 12b0f7b0796..59126603544 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -46,11 +46,11 @@ void item_init(void) } Item::Item(): - name_length(0), fixed(0) + name_length(0), fixed(0), + collation(default_charset(), DERIVATION_COERCIBLE) { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; - collation.set(default_charset(), DERIVATION_COERCIBLE); name= 0; decimals= 0; max_length= 0; @@ -114,13 +114,31 @@ void Item::cleanup() DBUG_PRINT("info", ("Item: 0x%lx", this)); DBUG_PRINT("info", ("Type: %d", (int)type())); fixed=0; + marker= 0; DBUG_VOID_RETURN; } + +/* + cleanup() item if it is 'fixed' + + SYNOPSIS + cleanup_processor() + arg - a dummy parameter, is not used here +*/ + +bool Item::cleanup_processor(byte *arg) +{ + if (fixed) + cleanup(); + return FALSE; +} + + Item_ident::Item_ident(const char *db_name_par,const char *table_name_par, const char *field_name_par) :orig_db_name(db_name_par), orig_table_name(table_name_par), - orig_field_name(field_name_par), changed_during_fix_field(0), + orig_field_name(field_name_par), db_name(db_name_par), table_name(table_name_par), field_name(field_name_par), cached_field_index(NO_CACHED_FIELD_INDEX), cached_table(0), depended_from(0) @@ -134,7 +152,6 @@ Item_ident::Item_ident(THD *thd, Item_ident *item) orig_db_name(item->orig_db_name), orig_table_name(item->orig_table_name), orig_field_name(item->orig_field_name), - changed_during_fix_field(0), db_name(item->db_name), table_name(item->table_name), field_name(item->field_name), @@ -151,11 +168,6 @@ void Item_ident::cleanup() table_name, orig_table_name, field_name, orig_field_name)); Item::cleanup(); - if (changed_during_fix_field) - { - *changed_during_fix_field= this; - changed_during_fix_field= 0; - } db_name= orig_db_name; table_name= orig_table_name; field_name= orig_field_name; @@ -267,6 +279,41 @@ bool Item::eq(const Item *item, bool binary_cmp) const } +Item *Item::safe_charset_converter(CHARSET_INFO *tocs) +{ + /* + Don't allow automatic conversion to non-Unicode charsets, + as it potentially loses data. + */ + if (!(tocs->state & MY_CS_UNICODE)) + return NULL; // safe conversion is not possible + return new Item_func_conv_charset(this, tocs); +} + + +Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs) +{ + Item_string *conv; + uint conv_errors; + String tmp, cstr, *ostr= val_str(&tmp); + cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors); + if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(), + cstr.charset(), + collation.derivation))) + { + /* + Safe conversion is not possible (or EOM). + We could not convert a string into the requested character set + without data loss. The target charset does not cover all the + characters from the string. Operation cannot be done correctly. + */ + return NULL; + } + conv->str_value.copy(); + return conv; +} + + bool Item_string::eq(const Item *item, bool binary_cmp) const { if (type() == item->type()) @@ -361,7 +408,43 @@ Item_splocal::type() const } -bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion) + +/* + Aggregate two collations together taking + into account their coercibility (aka derivation): + + 0 == DERIVATION_EXPLICIT - an explicitely written COLLATE clause + 1 == DERIVATION_NONE - a mix of two different collations + 2 == DERIVATION_IMPLICIT - a column + 3 == DERIVATION_COERCIBLE - a string constant + + The most important rules are: + + 1. If collations are the same: + chose this collation, and the strongest derivation. + + 2. If collations are different: + - Character sets may differ, but only if conversion without + data loss is possible. The caller provides flags whether + character set conversion attempts should be done. If no + flags are substituted, then the character sets must be the same. + Currently processed flags are: + MY_COLL_ALLOW_SUPERSET_CONV - allow conversion to a superset + MY_COLL_ALLOW_COERCIBLE_CONV - allow conversion of a coercible value + - two EXPLICIT collations produce an error, e.g. this is wrong: + CONCAT(expr1 collate latin1_swedish_ci, expr2 collate latin1_german_ci) + - the side with smaller derivation value wins, + i.e. a column is stronger than a string constant, + an explicit COLLATE clause is stronger than a column. + - if derivations are the same, we have DERIVATION_NONE, + we'll wait for an explicit COLLATE clause which possibly can + come from another argument later: for example, this is valid, + but we don't know yet when collecting the first two arguments: + CONCAT(latin1_swedish_ci_column, + latin1_german1_ci_column, + expr COLLATE latin1_german2_ci) +*/ +bool DTCollation::aggregate(DTCollation &dt, uint flags) { nagg++; if (!my_charset_same(collation, dt.collation)) @@ -392,28 +475,37 @@ bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion) else ; // Do nothing } - else if (superset_conversion) + else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) && + derivation < dt.derivation && + collation->state & MY_CS_UNICODE) { - if (derivation < dt.derivation && - collation->state & MY_CS_UNICODE) - ; // Do nothing - else if (dt.derivation < derivation && - dt.collation->state & MY_CS_UNICODE) - { - set(dt); - strong= nagg; - } - else - { - // Cannot convert to superset - set(0, DERIVATION_NONE); - return 1; - } + // Do nothing + } + else if ((flags & MY_COLL_ALLOW_SUPERSET_CONV) && + dt.derivation < derivation && + dt.collation->state & MY_CS_UNICODE) + { + set(dt); + strong= nagg; + } + else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && + derivation < dt.derivation && + dt.derivation == DERIVATION_COERCIBLE) + { + // Do nothing; + } + else if ((flags & MY_COLL_ALLOW_COERCIBLE_CONV) && + dt.derivation < derivation && + derivation == DERIVATION_COERCIBLE) + { + set(dt); + strong= nagg; } else { + // Cannot apply conversion set(0, DERIVATION_NONE); - return 1; + return 1; } } else if (derivation < dt.derivation) @@ -452,19 +544,47 @@ Item_field::Item_field(Field *f) have_privileges(0), any_privileges(0) { set_field(f); - collation.set(DERIVATION_IMPLICIT); - fixed= 1; + /* + field_name and talbe_name should not point to garbage + if this item is to be reused + */ + orig_table_name= orig_field_name= ""; } Item_field::Item_field(THD *thd, Field *f) - :Item_ident(NullS, thd->strdup(f->table_name), - thd->strdup(f->field_name)), + :Item_ident(f->table->table_cache_key, f->table_name, f->field_name), item_equal(0), no_const_subst(0), have_privileges(0), any_privileges(0) { + /* + We always need to provide Item_field with a fully qualified field + name to avoid ambiguity when executing prepared statements like + SELECT * from d1.t1, d2.t1; (assuming d1.t1 and d2.t1 have columns + with same names). + This is because prepared statements never deal with wildcards in + select list ('*') and always fix fields using fully specified path + (i.e. db.table.column). + No check for OOM: if db_name is NULL, we'll just get + "Field not found" error. + We need to copy db_name, table_name and field_name because they must + be allocated in the statement memory, not in table memory (the table + structure can go away and pop up again between subsequent executions + of a prepared statement). + */ + if (thd->current_arena->is_stmt_prepare()) + { + if (db_name) + orig_db_name= thd->strdup(db_name); + orig_table_name= thd->strdup(table_name); + orig_field_name= thd->strdup(field_name); + /* + We don't restore 'name' in cleanup because it's not changed + during execution. Still we need it to point to persistent + memory if this item is to be reused. + */ + name= (char*) orig_field_name; + } set_field(f); - collation.set(DERIVATION_IMPLICIT); - fixed= 1; } // Constructor need to process subselect with temporary tables (see Item) @@ -491,6 +611,21 @@ void Item_field::set_field(Field *field_par) db_name=field_par->table->table_cache_key; unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); collation.set(field_par->charset(), DERIVATION_IMPLICIT); + fixed= 1; +} + + +/* + Reset this item to point to a field from the new temporary table. + This is used when we create a new temporary table for each execution + of prepared statement. +*/ + +void Item_field::reset_field(Field *f) +{ + set_field(f); + /* 'name' is pointing at field->field_name of old field */ + name= (char*) f->field_name; } const char *Item_ident::full_name() const @@ -793,6 +928,12 @@ String *Item_null::val_str(String *str) } +Item *Item_null::safe_charset_converter(CHARSET_INFO *tocs) +{ + collation.set(tocs); + return this; +} + /*********************** Item_param related ******************************/ /* @@ -888,7 +1029,9 @@ bool Item_param::set_str(const char *str, ulong length) Assign string with no conversion: data is converted only after it's been written to the binary log. */ - if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin)) + uint dummy_errors; + if (str_value.copy(str, length, &my_charset_bin, &my_charset_bin, + &dummy_errors)) DBUG_RETURN(TRUE); state= STRING_VALUE; maybe_null= 0; @@ -1043,7 +1186,7 @@ int Item_param::save_in_field(Field *field, bool no_conversions) return field->store(str_value.ptr(), str_value.length(), str_value.charset()); case NULL_VALUE: - return set_field_to_null(field); + return set_field_to_null_with_conversions(field, no_conversions); case NO_VALUE: default: DBUG_ASSERT(0); @@ -1146,9 +1289,10 @@ String *Item_param::val_str(String* str) return str; case TIME_VALUE: { - if (str->reserve(MAX_DATE_REP_LENGTH)) + if (str->reserve(MAX_DATE_STRING_REP_LENGTH)) break; - TIME_to_string(&value.time, str); + str->length((uint) my_TIME_to_str(&value.time, (char*) str->ptr())); + str->set_charset(&my_charset_bin); return str; } case NULL_VALUE: @@ -1178,24 +1322,19 @@ const String *Item_param::query_val_str(String* str) const case TIME_VALUE: { char *buf, *ptr; - String tmp; str->length(0); /* TODO: in case of error we need to notify replication that binary log contains wrong statement */ - if (str->reserve(MAX_DATE_REP_LENGTH+3)) + if (str->reserve(MAX_DATE_STRING_REP_LENGTH+3)) break; /* Create date string inplace */ buf= str->c_ptr_quick(); ptr= buf; *ptr++= '\''; - tmp.set(ptr, MAX_DATE_REP_LENGTH, &my_charset_bin); - tmp.length(0); - TIME_to_string(&value.time, &tmp); - - ptr+= tmp.length(); + ptr+= (uint) my_TIME_to_str(&value.time, ptr); *ptr++= '\''; str->length((uint32) (ptr - buf)); break; @@ -1249,6 +1388,10 @@ bool Item_param::convert_str_value(THD *thd) value.cs_info.character_set_client, value.cs_info.final_character_set_of_str_value); } + else + str_value.set_charset(value.cs_info.final_character_set_of_str_value); + /* Here str_value is guaranteed to be in final_character_set_of_str_value */ + max_length= str_value.length(); decimals= 0; /* @@ -1373,7 +1516,7 @@ bool Item_ref_null_helper::get_date(TIME *ltime, uint fuzzydate) static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, Item_ident *item) { - // store pointer on SELECT_LEX from wich item is dependent + // store pointer on SELECT_LEX from which item is dependent item->depended_from= last; current->mark_as_dependent(last); if (thd->lex->describe & DESCRIBE_EXTENDED) @@ -1390,6 +1533,8 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, } + + /* Search a GROUP BY clause for a field with a certain name. @@ -1534,13 +1679,14 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) ORDER *group_list= (ORDER*) select->group_list.first; bool ambiguous_fields= FALSE; uint counter; + bool not_used; /* Search for a column or derived column named as 'ref' in the SELECT clause of the current select. */ if (!(select_ref= find_item_in_list(ref, *(select->get_item_list()), &counter, - REPORT_EXCEPT_NOT_FOUND))) + REPORT_EXCEPT_NOT_FOUND, ¬_used))) return NULL; /* Some error occurred. */ /* If this is a non-aggregated field inside HAVING, search in GROUP BY. */ @@ -1687,10 +1833,10 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) enum_parsing_place place= prev_subselect_item->parsing_place; /* Check table fields only if the subquery is used somewhere out of - HAVING or SELECT list, or the outer SELECT does not use grouping - (i.e. tables are accessible). + HAVING, or the outer SELECT does not use grouping (i.e. tables are + accessible). */ - if (((place != IN_HAVING && place != SELECT_LIST) || + if ((place != IN_HAVING || (outer_sel->with_sum_func == 0 && outer_sel->group_list.elements == 0)) && (from_field= find_field_in_tables(thd, this, table_list, @@ -1762,15 +1908,14 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) } else if (ref != not_found_item) { - /* Should be checked in resolve_ref_in_select_and_group(). */ + /* Should have been checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->fixed); - Item_ref *rf; - *reference= rf= new Item_ref(ref, reference, (char *) table_name, - (char *) field_name); - register_item_tree_changing(reference); + Item_ref *rf= new Item_ref(last->ref_pointer_array + counter, + (char *)table_name, (char *)field_name); if (!rf) return TRUE; + thd->change_item_tree(reference, rf); /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() @@ -1787,12 +1932,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) if (last->having_fix_field) { Item_ref *rf; - *reference= rf= new Item_ref(reference, *reference, - (cached_table->db[0]?cached_table->db:0), - (char *)cached_table->alias, - (char *)field_name); + rf= new Item_ref((cached_table->db[0] ? cached_table->db : 0), + (char*) cached_table->alias, (char*) field_name); if (!rf) return TRUE; + thd->change_item_tree(reference, rf); /* rf is Item_ref => never substitute other items (in this case) during fix_fields() => we can use rf after fix_fields() @@ -1861,6 +2005,14 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) return FALSE; } + +Item *Item_field::safe_charset_converter(CHARSET_INFO *tocs) +{ + no_const_subst= 1; + return Item::safe_charset_converter(tocs); +} + + void Item_field::cleanup() { DBUG_ENTER("Item_field::cleanup"); @@ -1871,6 +2023,7 @@ void Item_field::cleanup() I.e. we can drop 'field'. */ field= result_field= 0; + DBUG_VOID_RETURN; } /* @@ -1915,7 +2068,8 @@ Item_equal *Item_field::find_item_equal(COND_EQUAL *cond_equal) /* - Set a pointer to the multiple equality the field reference belongs to (if any) + Set a pointer to the multiple equality the field reference belongs to + (if any) SYNOPSIS equal_fields_propagator() @@ -1954,7 +2108,21 @@ Item *Item_field::equal_fields_propagator(byte *arg) /* - Set a pointer to the multiple equality the field reference belongs to (if any) + Mark the item to not be part of substitution if it's not a binary item + See comments in Arg_comparator::set_compare_func() for details +*/ + +Item *Item_field::set_no_const_sub(byte *arg) +{ + if (field->charset() != &my_charset_bin) + no_const_subst=1; + return this; +} + + +/* + Set a pointer to the multiple equality the field reference belongs to + (if any) SYNOPSIS replace_equal_field_processor() @@ -1990,6 +2158,7 @@ bool Item_field::replace_equal_field_processor(byte *arg) return 0; } + void Item::init_make_field(Send_field *tmp_field, enum enum_field_types field_type) { @@ -2000,7 +2169,9 @@ void Item::init_make_field(Send_field *tmp_field, tmp_field->table_name= empty_name; tmp_field->col_name= name; tmp_field->charsetnr= collation.collation->number; - tmp_field->flags=maybe_null ? 0 : NOT_NULL_FLAG; + tmp_field->flags= (maybe_null ? 0 : NOT_NULL_FLAG) | + (my_binary_compare(collation.collation) ? + BINARY_FLAG : 0); tmp_field->type=field_type; tmp_field->length=max_length; tmp_field->decimals=decimals; @@ -2629,15 +2800,15 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) enum_parsing_place place= prev_subselect_item->parsing_place; /* Check table fields only if the subquery is used somewhere out of - HAVING or SELECT list, or the outer SELECT does not use grouping - (i.e. tables are accessible). + HAVING or the outer SELECT does not use grouping (i.e. tables are + accessible). TODO: Here we could first find the field anyway, and then test this condition, so that we can give a better error message - ER_WRONG_FIELD_WITH_GROUP, instead of the less informative ER_BAD_FIELD_ERROR which we produce now. */ - if (((place != IN_HAVING && place != SELECT_LIST) || + if ((place != IN_HAVING || (!outer_sel->with_sum_func && outer_sel->group_list.elements == 0))) { @@ -2679,19 +2850,24 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), this->full_name(), current_thd->where); - ref= 0; + ref= 0; // Safety return TRUE; } - else if (from_field != not_found_field) + if (from_field != not_found_field) { - ref= 0; // To prevent "delete *ref;" on ~Item_ref() of this item + /* + Set ref to 0 as we are replacing this item with the found item and + this will ensure we get an error if this item would be used + elsewhere + */ + ref= 0; // Safety if (from_field != view_ref_found) { - Item_field* fld= new Item_field(from_field); - if (!((*reference)= fld)) + Item_field* fld; + if (!(fld= new Item_field(tmp))) return TRUE; - mark_as_dependent(thd, last, current_sel, fld); - register_item_tree_changing(reference); + thd->change_item_tree(reference, fld); + mark_as_dependent(thd, last, thd->lex->current_select, fld); return FALSE; } /* @@ -2757,8 +2933,6 @@ void Item_ref::cleanup() DBUG_ENTER("Item_ref::cleanup"); Item_ident::cleanup(); result_field= 0; - if (hook_ptr) - *hook_ptr= orig_item; DBUG_VOID_RETURN; } @@ -2881,7 +3055,6 @@ bool Item_default_value::fix_fields(THD *thd, def_field->move_field(def_field->table->default_values - def_field->table->record[0]); set_field(def_field); - fixed= 1; return 0; } @@ -2939,7 +3112,6 @@ bool Item_insert_value::fix_fields(THD *thd, set_field(new Field_null(0, 0, Field::NONE, tmp_field->field_name, tmp_field->table, &my_charset_bin)); } - fixed= 1; return 0; } @@ -3058,10 +3230,12 @@ Item_result item_cmp_type(Item_result a,Item_result b) } -Item *resolve_const_item(Item *item,Item *comp_item) +void resolve_const_item(THD *thd, Item **ref, Item *comp_item) { + Item *item= *ref; + Item *new_item; if (item->basic_const_item()) - return item; // Can't be better + return; // Can't be better Item_result res_type=item_cmp_type(comp_item->result_type(), item->result_type()); char *name=item->name; // Alloced by sql_alloc @@ -3072,27 +3246,32 @@ Item *resolve_const_item(Item *item,Item *comp_item) String tmp(buff,sizeof(buff),&my_charset_bin),*result; result=item->val_str(&tmp); if (item->null_value) - return new Item_null(name); - uint length=result->length(); - char *tmp_str=sql_strmake(result->ptr(),length); - return new Item_string(name,tmp_str,length,result->charset()); + new_item= new Item_null(name); + else + { + uint length= result->length(); + char *tmp_str= sql_strmake(result->ptr(), length); + new_item= new Item_string(name, tmp_str, length, result->charset()); + } } - if (res_type == INT_RESULT) + else if (res_type == INT_RESULT) { longlong result=item->val_int(); uint length=item->max_length; bool null_value=item->null_value; - return (null_value ? (Item*) new Item_null(name) : - (Item*) new Item_int(name,result,length)); + new_item= (null_value ? (Item*) new Item_null(name) : + (Item*) new Item_int(name, result, length)); } else { // It must REAL_RESULT double result=item->val(); uint length=item->max_length,decimals=item->decimals; bool null_value=item->null_value; - return (null_value ? (Item*) new Item_null(name) : - (Item*) new Item_real(name,result,decimals,length)); + new_item= (null_value ? (Item*) new Item_null(name) : (Item*) + new Item_real(name, result, decimals, length)); } + if (new_item) + thd->change_item_tree(ref, new_item); } /* @@ -3319,6 +3498,7 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item) else field_example= 0; max_length= real_length(item); + maybe_null= item->maybe_null; collation.set(item->collation); } @@ -3336,62 +3516,90 @@ static Item_result type_convertor[4][4]= {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT}, {ROW_RESULT, ROW_RESULT, ROW_RESULT, ROW_RESULT}}; + +/* + Values of 'from' field can be stored in 'to' field. + + SYNOPSIS + is_attr_compatible() + from Item which values should be saved + to Item where values should be saved + + RETURN + 1 can be saved + 0 can not be saved +*/ + +inline bool is_attr_compatible(Item *from, Item *to) +{ + return ((to->max_length >= from->max_length) && + (to->maybe_null || !from->maybe_null) && + (to->result_type() != STRING_RESULT || + from->result_type() != STRING_RESULT || + my_charset_same(from->collation.collation, + to->collation.collation))); +} + + bool Item_type_holder::join_types(THD *thd, Item *item) { uint32 new_length= real_length(item); - bool change_field= 0, skip_store_field= 0; - Item_result new_type= type_convertor[item_type][item->result_type()]; + bool use_new_field= 0, use_expression_type= 0; + Item_result new_result_type= type_convertor[item_type][item->result_type()]; + bool item_is_a_field= item->type() == Item::FIELD_ITEM; - // we have both fields - if (field_example && item->type() == Item::FIELD_ITEM) + /* + Check if both items point to fields: in this case we + can adjust column types of result table in the union smartly. + */ + if (field_example && item_is_a_field) { Field *field= ((Item_field *)item)->field; - if (field_example->field_cast_type() != field->field_cast_type()) + /* Can 'field_example' field store data of the column? */ + if ((use_new_field= + (!field->field_cast_compatible(field_example->field_cast_type()) || + !is_attr_compatible(item, this)))) { - if (!(change_field= - field_example->field_cast_compatible(field->field_cast_type()))) - { - /* - if old field can't store value of 'worse' new field we will make - decision about result field type based only on Item result type - */ - if (!field->field_cast_compatible(field_example->field_cast_type())) - skip_store_field= 1; - } + /* + The old field can't store value of the new field. + Check if the new field can store value of the old one. + */ + use_expression_type|= + (!field_example->field_cast_compatible(field->field_cast_type()) || + !is_attr_compatible(this, item)); } } - - // size/type should be changed - if (change_field || - (new_type != item_type) || - (max_length < new_length) || - ((new_type == INT_RESULT) && - (decimals < item->decimals)) || - (!maybe_null && item->maybe_null) || - (item_type == STRING_RESULT && new_type == STRING_RESULT && - !my_charset_same(collation.collation, item->collation.collation))) - { - // new field has some parameters worse then current - skip_store_field|= (change_field && - (max_length > new_length) || - ((new_type == INT_RESULT) && - (decimals > item->decimals)) || - (maybe_null && !item->maybe_null) || - (item_type == STRING_RESULT && - new_type == STRING_RESULT && - !my_charset_same(collation.collation, - item->collation.collation))); + else if (field_example || item_is_a_field) + { /* - It is safe assign pointer on field, because it will be used just after - all JOIN::prepare calls and before any SELECT execution + Expression types can't be mixed with field types, we have to use + expression types. */ - if (skip_store_field || item->type() != Item::FIELD_ITEM) + use_new_field= 1; // make next if test easier + use_expression_type= 1; + } + + /* Check whether size/type of the result item should be changed */ + if (use_new_field || + (new_result_type != item_type) || (new_length > max_length) || + (!maybe_null && item->maybe_null) || + (item_type == STRING_RESULT && + collation.collation != item->collation.collation)) + { + const char *old_cs,*old_derivation; + if (use_expression_type || !item_is_a_field) field_example= 0; else + { + /* + It is safe to assign a pointer to field here, because it will be used + before any table is closed. + */ field_example= ((Item_field*) item)->field; + } - const char *old_cs= collation.collation->name, - *old_derivation= collation.derivation_name(); + old_cs= collation.collation->name; + old_derivation= collation.derivation_name(); if (item_type == STRING_RESULT && collation.aggregate(item->collation)) { my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), @@ -3405,18 +3613,18 @@ bool Item_type_holder::join_types(THD *thd, Item *item) max_length= max(max_length, new_length); decimals= max(decimals, item->decimals); maybe_null|= item->maybe_null; - item_type= new_type; + item_type= new_result_type; } DBUG_ASSERT(item_type != ROW_RESULT); return 0; } + uint32 Item_type_holder::real_length(Item *item) { if (item->type() == Item::FIELD_ITEM) - { return ((Item_field *)item)->max_disp_length(); - } + switch (item->result_type()) { case STRING_RESULT: @@ -3452,6 +3660,14 @@ String *Item_type_holder::val_str(String*) return 0; } +void Item_result_field::cleanup() +{ + DBUG_ENTER("Item_result_field::cleanup()"); + Item::cleanup(); + result_field= 0; + DBUG_VOID_RETURN; +} + /***************************************************************************** ** Instantiate templates *****************************************************************************/ @@ -3460,5 +3676,6 @@ String *Item_type_holder::val_str(String*) template class List; template class List_iterator; template class List_iterator_fast; +template class List_iterator_fast; template class List; #endif -- cgit v1.2.1 From baf1c89e3d66bd4d66555b3662d522adbabca505 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 18:20:40 +0400 Subject: A fix (bug #6564: QUOTE(NULL) returns NULL, not the string 'NULL') --- sql/item_strfunc.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9248cbc0217..53a9d3fe219 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2142,9 +2142,12 @@ String* Item_func_inet_ntoa::val_str(String* str) This function is very useful when you want to generate SQL statements - RETURN VALUES + NOTE + QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes). + + RETURN VALUES str Quoted string - NULL Argument to QUOTE() was NULL or out of memory. + NULL Out of memory. */ #define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7)) @@ -2168,7 +2171,12 @@ String *Item_func_quote::val_str(String *str) String *arg= args[0]->val_str(str); uint arg_length, new_length; if (!arg) // Null argument - goto null; + { + str->copy("NULL", 4); // Return the string 'NULL' + null_value= 0; + return str; + } + arg_length= arg->length(); new_length= arg_length+2; /* for beginning and ending ' signs */ -- cgit v1.2.1 From e5fd013fdf6c8664daa0bbdcaf0d22bf44e90d62 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 16:00:50 +0100 Subject: Fixing filename case problems in sql_base.cc for views on MacOS X. (With help from sanja :) sql/sql_base.cc: Fixing filename case problems for views on MacOS X. (With help from sanja :) --- sql/sql_base.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4fae481e5f2..1cee6d2c3a6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -582,6 +582,7 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, if ((!strcmp(table->db, db_name) && !strcmp(table->real_name, table_name)) || (table->view && + table->table->table_cache_key && // it is not temporary table !my_strcasecmp(table_alias_charset, table->table->table_cache_key, db_name) && !my_strcasecmp(table_alias_charset, @@ -626,6 +627,9 @@ TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) TABLE_LIST *res; const char *d_name= table->db, *t_name= table->real_name; char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME]; + /* temporary table is always unique */ + if (table->table && table->table->tmp_table != NO_TMP_TABLE) + return 0; if (table->view) { /* it is view and table opened */ @@ -643,11 +647,6 @@ TABLE_LIST* unique_table(TABLE_LIST *table, TABLE_LIST *table_list) d_name= table->table->table_cache_key; t_name= table->table->table_name; } - if (d_name == 0) - { - /* it's temporary table => always unique */ - return 0; - } } DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name)); -- cgit v1.2.1 From 7ecaf256564b2b540f31e6080348e9e9c76ab261 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 20:16:38 +0200 Subject: post-merge fixes for WL#1972 sql/item.cc: post-merge fixes sql/sql_select.cc: post-merge fixes --- sql/item.cc | 5 ++--- sql/sql_select.cc | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 59126603544..8d422eef39c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1911,8 +1911,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) /* Should have been checked in resolve_ref_in_select_and_group(). */ DBUG_ASSERT(*ref && (*ref)->fixed); - Item_ref *rf= new Item_ref(last->ref_pointer_array + counter, - (char *)table_name, (char *)field_name); + Item_ref *rf= new Item_ref(ref, (char *)table_name, (char *)field_name); if (!rf) return TRUE; thd->change_item_tree(reference, rf); @@ -2864,7 +2863,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) if (from_field != view_ref_found) { Item_field* fld; - if (!(fld= new Item_field(tmp))) + if (!(fld= new Item_field(from_field))) return TRUE; thd->change_item_tree(reference, fld); mark_as_dependent(thd, last, thd->lex->current_select, fld); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 924b74e2e6e..89edc06139c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11288,8 +11288,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, thd->is_fatal_error)) return 1; // Wrong field uint el= all_fields.elements; - all_fields.push_front(it); // Add new field to field list - ref_pointer_array[el]= it; + all_fields.push_front(order_item); // Add new field to field list + ref_pointer_array[el]= order_item; order->item= ref_pointer_array + el; return 0; } -- cgit v1.2.1 From 2e6fb936e8ad2ab2dcd26176640a9d43ee7abc26 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 21:39:35 +0300 Subject: Rename: Item::val -> Item::val_real(). sql/filesort.cc: val -> val_real sql/item.cc: val -> val_real sql/item.h: val -> val_real sql/item_buff.cc: val -> val_real sql/item_cmpfunc.cc: val -> val_real sql/item_cmpfunc.h: val -> val_real sql/item_func.cc: val -> val_real sql/item_func.h: val -> val_real sql/item_geofunc.cc: val -> val_real sql/item_geofunc.h: val -> val_real sql/item_row.h: val -> val_real sql/item_strfunc.cc: val -> val_real sql/item_strfunc.h: val -> val_real sql/item_subselect.cc: val -> val_real sql/item_subselect.h: val -> val_real sql/item_sum.cc: val -> val_real sql/item_sum.h: val -> val_real sql/item_timefunc.h: val -> val_real sql/item_uniq.h: val -> val_real sql/procedure.h: val -> val_real sql/sp_head.cc: val -> val_real sql/sql_analyse.cc: val -> val_real sql/sql_class.cc: val -> val_real sql/sql_select.cc: val -> val_real --- sql/filesort.cc | 2 +- sql/item.cc | 27 +++++---- sql/item.h | 40 +++++++------- sql/item_buff.cc | 2 +- sql/item_cmpfunc.cc | 56 +++++++++---------- sql/item_cmpfunc.h | 14 ++--- sql/item_func.cc | 150 +++++++++++++++++++++++++------------------------- sql/item_func.h | 95 +++++++++++++++++--------------- sql/item_geofunc.cc | 12 ++-- sql/item_geofunc.h | 8 +-- sql/item_row.h | 2 +- sql/item_strfunc.cc | 8 +-- sql/item_strfunc.h | 4 +- sql/item_subselect.cc | 8 +-- sql/item_subselect.h | 6 +- sql/item_sum.cc | 66 +++++++++++----------- sql/item_sum.h | 50 ++++++++++------- sql/item_timefunc.h | 18 +++--- sql/item_uniq.h | 4 +- sql/procedure.h | 6 +- sql/sp_head.cc | 4 +- sql/sql_analyse.cc | 8 +-- sql/sql_class.cc | 2 +- sql/sql_select.cc | 8 +-- 24 files changed, 306 insertions(+), 294 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index 3e56acefea9..1f80728095d 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -707,7 +707,7 @@ static void make_sortkey(register SORTPARAM *param, } case REAL_RESULT: { - double value=item->val(); + double value= item->val_real(); if ((maybe_null=item->null_value)) { bzero((char*) to,sort_field->length+1); diff --git a/sql/item.cc b/sql/item.cc index 8d422eef39c..429b8f63afa 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -711,7 +711,7 @@ String *Item_field::val_str(String *str) return field->val_str(str,&str_value); } -double Item_field::val() +double Item_field::val_real() { DBUG_ASSERT(fixed == 1); if ((null_value=field->is_null())) @@ -904,7 +904,7 @@ void Item_string::print(String *str) bool Item_null::eq(const Item *item, bool binary_cmp) const { return item->type() == type(); } -double Item_null::val() +double Item_null::val_real() { // following assert is redundant, because fixed=1 assigned in constructor DBUG_ASSERT(fixed == 1); @@ -1221,7 +1221,7 @@ bool Item_param::get_date(TIME *res, uint fuzzydate) } -double Item_param::val() +double Item_param::val_real() { switch (state) { case REAL_VALUE: @@ -1469,7 +1469,7 @@ bool Item::fix_fields(THD *thd, return 0; } -double Item_ref_null_helper::val() +double Item_ref_null_helper::val_real() { DBUG_ASSERT(fixed == 1); double tmp= (*ref)->val_result(); @@ -2385,7 +2385,7 @@ int Item::save_in_field(Field *field, bool no_conversions) } else if (result_type() == REAL_RESULT) { - double nr=val(); + double nr= val_real(); if (null_value) return set_field_to_null(field); field->set_notnull(); @@ -2467,7 +2467,7 @@ Item_real::Item_real(const char *str_arg, uint length) int Item_real::save_in_field(Field *field, bool no_conversions) { - double nr=val(); + double nr= val_real(); if (null_value) return set_field_to_null(field); field->set_notnull(); @@ -2629,15 +2629,14 @@ bool Item::send(Protocol *protocol, String *buffer) case MYSQL_TYPE_FLOAT: { float nr; - nr= (float) val(); + nr= (float) val_real(); if (!null_value) result= protocol->store(nr, decimals, buffer); break; } case MYSQL_TYPE_DOUBLE: { - double nr; - nr= val(); + double nr= val_real(); if (!null_value) result= protocol->store(nr, decimals, buffer); break; @@ -2961,7 +2960,7 @@ double Item_ref::val_result() return 0.0; return result_field->val_real(); } - return val(); + return val_real(); } @@ -3263,7 +3262,7 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item) } else { // It must REAL_RESULT - double result=item->val(); + double result= item->val_real(); uint length=item->max_length,decimals=item->decimals; bool null_value=item->null_value; new_item= (null_value ? (Item*) new Item_null(name) : (Item*) @@ -3298,7 +3297,7 @@ bool field_is_equal_to_item(Field *field,Item *item) } if (res_type == INT_RESULT) return 1; // Both where of type int - double result=item->val(); + double result= item->val_real(); if (item->null_value) return 1; return result == field->val_real(); @@ -3371,7 +3370,7 @@ void Item_cache_str::store(Item *item) } -double Item_cache_str::val() +double Item_cache_str::val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -3639,7 +3638,7 @@ uint32 Item_type_holder::real_length(Item *item) } } -double Item_type_holder::val() +double Item_type_holder::val_real() { DBUG_ASSERT(0); // should never be called return 0.0; diff --git a/sql/item.h b/sql/item.h index 93c396b95b0..329c25073ee 100644 --- a/sql/item.h +++ b/sql/item.h @@ -186,7 +186,7 @@ public: virtual enum_field_types field_type() const; virtual enum Type type() const =0; /* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */ - virtual double val()=0; + virtual double val_real()=0; virtual longlong val_int()=0; /* Return string representation of this item object. @@ -217,7 +217,7 @@ public: virtual Field *get_tmp_table_field() { return 0; } virtual Field *tmp_table_field(TABLE *t_arg) { return 0; } virtual const char *full_name() const { return name ? name : "???"; } - virtual double val_result() { return val(); } + virtual double val_result() { return val_real(); } virtual longlong val_int_result() { return val_int(); } virtual String *str_result(String* tmp) { return val_str(tmp); } /* bit map of tables used by item */ @@ -362,10 +362,10 @@ public: // the item in the frame enum Type type() const; - inline double val() + inline double val_real() { Item *it= this_item(); - double ret= it->val(); + double ret= it->val_real(); Item::null_value= it->null_value; return ret; } @@ -526,7 +526,7 @@ public: Item_field(Field *field); enum Type type() const { return FIELD_ITEM; } bool eq(const Item *item, bool binary_cmp) const; - double val(); + double val_real(); longlong val_int(); String *val_str(String*); double val_result(); @@ -580,7 +580,7 @@ public: } enum Type type() const { return NULL_ITEM; } bool eq(const Item *item, bool binary_cmp) const; - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); int save_in_field(Field *field, bool no_conversions); @@ -669,7 +669,7 @@ public: enum Type type() const { return item_type; } enum_field_types field_type() const { return param_type; } - double val(); + double val_real(); longlong val_int(); String *val_str(String*); bool get_time(TIME *tm); @@ -726,7 +726,7 @@ public: enum Item_result result_type () const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } String *val_str(String*); int save_in_field(Field *field, bool no_conversions); bool basic_const_item() const { return 1; } @@ -755,7 +755,7 @@ public: Item_uint(const char *str_arg, uint length); Item_uint(uint32 i) :Item_int((longlong) i, 10) { unsigned_flag= 1; } - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return ulonglong2double((ulonglong)value); } String *val_str(String*); Item *new_item() { return new Item_uint(name,max_length); } @@ -784,7 +784,7 @@ public: int save_in_field(Field *field, bool no_conversions); enum Type type() const { return REAL_ITEM; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } - double val() { DBUG_ASSERT(fixed == 1); return value; } + double val_real() { DBUG_ASSERT(fixed == 1); return value; } longlong val_int() { DBUG_ASSERT(fixed == 1); @@ -855,7 +855,7 @@ public: fixed= 1; } enum Type type() const { return STRING_ITEM; } - double val() + double val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -945,7 +945,7 @@ class Item_varbinary :public Item public: Item_varbinary(const char *str,uint str_length); enum Type type() const { return VARBIN_ITEM; } - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_varbinary::val_int(); } longlong val_int(); bool basic_const_item() const { return 1; } @@ -997,7 +997,7 @@ public: enum Type type() const { return REF_ITEM; } bool eq(const Item *item, bool binary_cmp) const { return ref && (*ref)->eq(item, binary_cmp); } - double val() + double val_real() { double tmp=(*ref)->val_result(); null_value=(*ref)->null_value; @@ -1062,7 +1062,7 @@ public: Item_ref_null_helper(Item_in_subselect* master, Item **item, const char *table_name_par, const char *field_name_par): Item_ref(item, table_name_par, field_name_par), owner(master) {} - double val(); + double val_real(); longlong val_int(); String* val_str(String* s); bool get_date(TIME *ltime, uint fuzzydate); @@ -1130,7 +1130,7 @@ public: enum Type type() const { return COPY_STR_ITEM; } enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return cached_field_type; } - double val() + double val_real() { int err; return (null_value ? 0.0 : @@ -1358,7 +1358,7 @@ public: Item_cache_int(): Item_cache() {} void store(Item *item); - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } String* val_str(String *str) { @@ -1376,7 +1376,7 @@ public: Item_cache_real(): Item_cache() {} void store(Item *item); - double val() { DBUG_ASSERT(fixed == 1); return value; } + double val_real() { DBUG_ASSERT(fixed == 1); return value; } longlong val_int() { DBUG_ASSERT(fixed == 1); @@ -1398,7 +1398,7 @@ public: Item_cache_str(): Item_cache() { } void store(Item *item); - double val(); + double val_real(); longlong val_int(); String* val_str(String *) { DBUG_ASSERT(fixed == 1); return value; } enum Item_result result_type() const { return STRING_RESULT; } @@ -1430,7 +1430,7 @@ public: { illegal_method_call((const char*)"make_field"); }; - double val() + double val_real() { illegal_method_call((const char*)"val"); return 0; @@ -1481,7 +1481,7 @@ public: Item_result result_type () const { return item_type; } enum Type type() const { return TYPE_HOLDER; } - double val(); + double val_real(); longlong val_int(); String *val_str(String*); bool join_types(THD *thd, Item *); diff --git a/sql/item_buff.cc b/sql/item_buff.cc index 1559cfe958e..66de26dba9a 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -70,7 +70,7 @@ Item_str_buff::~Item_str_buff() bool Item_real_buff::cmp(void) { - double nr=item->val(); + double nr= item->val_real(); if (null_value != item->null_value || nr != value) { null_value= item->null_value; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 905250ed96f..105c5c4402e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -104,7 +104,7 @@ Item_bool_func2* Le_creator::create(Item *a, Item *b) const longlong Item_func_not::val_int() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return !null_value && value == 0 ? 1 : 0; } @@ -116,7 +116,7 @@ longlong Item_func_not::val_int() longlong Item_func_not_all::val_int() { DBUG_ASSERT(fixed == 1); - double value= args[0]->val(); + double value= args[0]->val_real(); if (abort_on_null) { null_value= 0; @@ -384,10 +384,10 @@ int Arg_comparator::compare_e_binary_string() int Arg_comparator::compare_real() { - double val1= (*a)->val(); + double val1= (*a)->val_real(); if (!(*a)->null_value) { - double val2= (*b)->val(); + double val2= (*b)->val_real(); if (!(*b)->null_value) { owner->null_value= 0; @@ -402,8 +402,8 @@ int Arg_comparator::compare_real() int Arg_comparator::compare_e_real() { - double val1= (*a)->val(); - double val2= (*b)->val(); + double val1= (*a)->val_real(); + double val2= (*b)->val_real(); if ((*a)->null_value || (*b)->null_value) return test((*a)->null_value && (*b)->null_value); return test(val1 == val2); @@ -754,7 +754,7 @@ void Item_func_interval::fix_length_and_dec() (intervals=(double*) sql_alloc(sizeof(double)*(row->cols()-1)))) { for (uint i=1 ; i < row->cols(); i++) - intervals[i-1]=row->el(i)->val(); + intervals[i-1]= row->el(i)->val_real(); } } maybe_null= 0; @@ -776,7 +776,7 @@ void Item_func_interval::fix_length_and_dec() longlong Item_func_interval::val_int() { DBUG_ASSERT(fixed == 1); - double value= row->el(0)->val(); + double value= row->el(0)->val_real(); uint i; if (row->el(0)->null_value) @@ -799,7 +799,7 @@ longlong Item_func_interval::val_int() for (i=1 ; i < row->cols() ; i++) { - if (row->el(i)->val() > value) + if (row->el(i)->val_real() > value) return i-1; } return i-1; @@ -873,7 +873,7 @@ longlong Item_func_between::val_int() } else if (cmp_type == INT_RESULT) { - longlong value=args[0]->val_int(),a,b; + longlong value=args[0]->val_int(), a, b; if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ a=args[1]->val_int(); @@ -893,11 +893,11 @@ longlong Item_func_between::val_int() } else { - double value=args[0]->val(),a,b; + double value= args[0]->val_real(),a,b; if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ - a=args[1]->val(); - b=args[2]->val(); + a= args[1]->val_real(); + b= args[2]->val_real(); if (!args[1]->null_value && !args[2]->null_value) return (value >= a && value <= b) ? 1 : 0; if (args[1]->null_value && args[2]->null_value) @@ -954,16 +954,16 @@ Field *Item_func_ifnull::tmp_table_field(TABLE *table) } double -Item_func_ifnull::val() +Item_func_ifnull::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if (!args[0]->null_value) { null_value=0; return value; } - value=args[1]->val(); + value= args[1]->val_real(); if ((null_value=args[1]->null_value)) return 0.0; return value; @@ -1042,11 +1042,11 @@ Item_func_if::fix_length_and_dec() double -Item_func_if::val() +Item_func_if::val_real() { DBUG_ASSERT(fixed == 1); Item *arg= args[0]->val_int() ? args[1] : args[2]; - double value=arg->val(); + double value= arg->val_real(); null_value=arg->null_value; return value; } @@ -1095,7 +1095,7 @@ Item_func_nullif::fix_length_and_dec() */ double -Item_func_nullif::val() +Item_func_nullif::val_real() { DBUG_ASSERT(fixed == 1); double value; @@ -1104,7 +1104,7 @@ Item_func_nullif::val() null_value=1; return 0.0; } - value=args[0]->val(); + value= args[0]->val_real(); null_value=args[0]->null_value; return value; } @@ -1179,7 +1179,7 @@ Item *Item_func_case::find_item(String *str) return else_expr_num != -1 ? args[else_expr_num] : 0; break; case REAL_RESULT: - first_expr_real= args[first_expr_num]->val(); + first_expr_real= args[first_expr_num]->val_real(); if (args[first_expr_num]->null_value) return else_expr_num != -1 ? args[else_expr_num] : 0; break; @@ -1212,7 +1212,7 @@ Item *Item_func_case::find_item(String *str) return args[i+1]; break; case REAL_RESULT: - if (args[i]->val()==first_expr_real && !args[i]->null_value) + if (args[i]->val_real() == first_expr_real && !args[i]->null_value) return args[i+1]; break; case ROW_RESULT: @@ -1264,7 +1264,7 @@ longlong Item_func_case::val_int() return res; } -double Item_func_case::val() +double Item_func_case::val_real() { DBUG_ASSERT(fixed == 1); char buff[MAX_FIELD_WIDTH]; @@ -1277,7 +1277,7 @@ double Item_func_case::val() null_value=1; return 0; } - res=item->val(); + res= item->val_real(); null_value=item->null_value; return res; } @@ -1400,13 +1400,13 @@ longlong Item_func_coalesce::val_int() return 0; } -double Item_func_coalesce::val() +double Item_func_coalesce::val_real() { DBUG_ASSERT(fixed == 1); null_value=0; for (uint i=0 ; i < arg_count ; i++) { - double res=args[i]->val(); + double res= args[i]->val_real(); if (!args[i]->null_value) return res; } @@ -1559,12 +1559,12 @@ in_double::in_double(uint elements) void in_double::set(uint pos,Item *item) { - ((double*) base)[pos]=item->val(); + ((double*) base)[pos]= item->val_real(); } byte *in_double::get_value(Item *item) { - tmp= item->val(); + tmp= item->val_real(); if (item->null_value) return 0; /* purecov: inspected */ return (byte*) &tmp; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index af2c385b296..02d5f6a1f7a 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -420,7 +420,7 @@ public: Item_func_ifnull(Item *a,Item *b) :Item_func(a,b), cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); enum Item_result result_type () const { return cached_result_type; } @@ -439,7 +439,7 @@ public: Item_func_if(Item *a,Item *b,Item *c) :Item_func(a,b,c), cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); enum Item_result result_type () const { return cached_result_type; } @@ -462,7 +462,7 @@ public: Item_func_nullif(Item *a,Item *b) :Item_bool_func2(a,b), cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); enum Item_result result_type () const { return cached_result_type; } @@ -481,7 +481,7 @@ public: Item_func_coalesce(List &list) :Item_func(list),cached_result_type(INT_RESULT) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); @@ -517,7 +517,7 @@ public: } set_arguments(list); } - double val(); + double val_real(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); @@ -674,11 +674,11 @@ class cmp_item_real :public cmp_item public: void store_value(Item *item) { - value= item->val(); + value= item->val_real(); } int cmp(Item *arg) { - return value != arg->val(); + return value != arg->val_real(); } int compare(cmp_item *c) { diff --git a/sql/item_func.cc b/sql/item_func.cc index 185d4f115ad..d5b11ce78a5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -516,7 +516,7 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) String *Item_real_func::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals, &my_charset_bin); @@ -539,7 +539,7 @@ String *Item_num_func::val_str(String *str) } else { - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -616,7 +616,7 @@ String *Item_num_op::val_str(String *str) } else { - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -643,10 +643,10 @@ void Item_func_unsigned::print(String *str) } -double Item_func_plus::val() +double Item_func_plus::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val()+args[1]->val(); + double value= args[0]->val_real() + args[1]->val_real(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; return value; @@ -662,7 +662,7 @@ longlong Item_func_plus::val_int() return 0; return value; } - return (longlong) Item_func_plus::val(); + return (longlong) Item_func_plus::val_real(); } @@ -680,10 +680,10 @@ void Item_func_minus::fix_length_and_dec() } -double Item_func_minus::val() +double Item_func_minus::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val() - args[1]->val(); + double value= args[0]->val_real() - args[1]->val_real(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; return value; @@ -699,14 +699,14 @@ longlong Item_func_minus::val_int() return 0; return value; } - return (longlong) Item_func_minus::val(); + return (longlong) Item_func_minus::val_real(); } -double Item_func_mul::val() +double Item_func_mul::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val()*args[1]->val(); + double value= args[0]->val_real() * args[1]->val_real(); if ((null_value=args[0]->null_value || args[1]->null_value)) return 0.0; /* purecov: inspected */ return value; @@ -722,15 +722,15 @@ longlong Item_func_mul::val_int() return 0; /* purecov: inspected */ return value; } - return (longlong) Item_func_mul::val(); + return (longlong) Item_func_mul::val_real(); } -double Item_func_div::val() +double Item_func_div::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); - double val2=args[1]->val(); + double value= args[0]->val_real(); + double val2= args[1]->val_real(); if ((null_value= args[0]->null_value || args[1]->null_value)) return 0.0; if (val2 == 0.0) @@ -758,7 +758,7 @@ longlong Item_func_div::val_int() } return value/val2; } - return (longlong) Item_func_div::val(); + return (longlong) Item_func_div::val_real(); } @@ -800,11 +800,11 @@ void Item_func_int_div::fix_length_and_dec() } -double Item_func_mod::val() +double Item_func_mod::val_real() { DBUG_ASSERT(fixed == 1); - double value= args[0]->val(); - double val2= args[1]->val(); + double value= args[0]->val_real(); + double val2= args[1]->val_real(); if ((null_value= args[0]->null_value || args[1]->null_value)) return 0.0; /* purecov: inspected */ if (val2 == 0.0) @@ -836,10 +836,10 @@ void Item_func_mod::fix_length_and_dec() } -double Item_func_neg::val() +double Item_func_neg::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return -value; } @@ -879,10 +879,10 @@ void Item_func_neg::fix_length_and_dec() } -double Item_func_abs::val() +double Item_func_abs::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return fabs(value); } @@ -911,10 +911,10 @@ void Item_func_abs::fix_length_and_dec() /* Gateway to natural LOG function */ -double Item_func_ln::val() +double Item_func_ln::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; return log(value); @@ -925,15 +925,15 @@ double Item_func_ln::val() We have to check if all values are > zero and first one is not one as these are the cases then result is not a number. */ -double Item_func_log::val() +double Item_func_log::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; if (arg_count == 2) { - double value2= args[1]->val(); + double value2= args[1]->val_real(); if ((null_value=(args[1]->null_value || value2 <= 0.0 || value == 1.0))) return 0.0; return log(value2) / log(value); @@ -941,47 +941,47 @@ double Item_func_log::val() return log(value); } -double Item_func_log2::val() +double Item_func_log2::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; return log(value) / M_LN2; } -double Item_func_log10::val() +double Item_func_log10::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value <= 0.0))) return 0.0; /* purecov: inspected */ return log10(value); } -double Item_func_exp::val() +double Item_func_exp::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; /* purecov: inspected */ return exp(value); } -double Item_func_sqrt::val() +double Item_func_sqrt::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || value < 0))) return 0.0; /* purecov: inspected */ return sqrt(value); } -double Item_func_pow::val() +double Item_func_pow::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); - double val2=args[1]->val(); + double value= args[0]->val_real(); + double val2= args[1]->val_real(); if ((null_value=(args[0]->null_value || args[1]->null_value))) return 0.0; /* purecov: inspected */ return pow(value,val2); @@ -989,35 +989,35 @@ double Item_func_pow::val() // Trigonometric functions -double Item_func_acos::val() +double Item_func_acos::val_real() { DBUG_ASSERT(fixed == 1); // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) - volatile double value=args[0]->val(); + volatile double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) return 0.0; return fix_result(acos(value)); } -double Item_func_asin::val() +double Item_func_asin::val_real() { DBUG_ASSERT(fixed == 1); // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug) - volatile double value=args[0]->val(); + volatile double value= args[0]->val_real(); if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) return 0.0; return fix_result(asin(value)); } -double Item_func_atan::val() +double Item_func_atan::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; if (arg_count == 2) { - double val2= args[1]->val(); + double val2= args[1]->val_real(); if ((null_value=args[1]->null_value)) return 0.0; return fix_result(atan2(value,val2)); @@ -1025,28 +1025,28 @@ double Item_func_atan::val() return fix_result(atan(value)); } -double Item_func_cos::val() +double Item_func_cos::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; return fix_result(cos(value)); } -double Item_func_sin::val() +double Item_func_sin::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; return fix_result(sin(value)); } -double Item_func_tan::val() +double Item_func_tan::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0.0; return fix_result(tan(value)); @@ -1110,7 +1110,7 @@ void Item_func_integer::fix_length_and_dec() longlong Item_func_ceiling::val_int() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return (longlong) ceil(value); } @@ -1119,7 +1119,7 @@ longlong Item_func_floor::val_int() { DBUG_ASSERT(fixed == 1); // the volatile's for BUG #3051 to calm optimizer down (because of gcc's bug) - volatile double value=args[0]->val(); + volatile double value= args[0]->val_real(); null_value=args[0]->null_value; return (longlong) floor(value); } @@ -1138,10 +1138,10 @@ void Item_func_round::fix_length_and_dec() } } -double Item_func_round::val() +double Item_func_round::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); int dec=(int) args[1]->val_int(); uint abs_dec=abs(dec); double tmp; @@ -1224,7 +1224,7 @@ void Item_func_rand::update_used_tables() } -double Item_func_rand::val() +double Item_func_rand::val_real() { DBUG_ASSERT(fixed == 1); return my_rnd(rand); @@ -1233,16 +1233,16 @@ double Item_func_rand::val() longlong Item_func_sign::val_int() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); null_value=args[0]->null_value; return value < 0.0 ? -1 : (value > 0 ? 1 : 0); } -double Item_func_units::val() +double Item_func_units::val_real() { DBUG_ASSERT(fixed == 1); - double value=args[0]->val(); + double value= args[0]->val_real(); if ((null_value=args[0]->null_value)) return 0; return value*mul+add; @@ -1288,7 +1288,7 @@ String *Item_func_min_max::val_str(String *str) } case REAL_RESULT: { - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -1332,7 +1332,7 @@ String *Item_func_min_max::val_str(String *str) } -double Item_func_min_max::val() +double Item_func_min_max::val_real() { DBUG_ASSERT(fixed == 1); double value=0.0; @@ -1341,12 +1341,12 @@ double Item_func_min_max::val() { if (null_value) { - value=args[i]->val(); + value= args[i]->val_real(); null_value=args[i]->null_value; } else { - double tmp=args[i]->val(); + double tmp= args[i]->val_real(); if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0) value=tmp; } @@ -1502,10 +1502,10 @@ longlong Item_func_field::val_int() } else { - double val= args[0]->val(); + double val= args[0]->val_real(); for (uint i=1; i < arg_count ; i++) { - if (val == args[i]->val()) + if (val == args[i]->val_real()) return (longlong) (i); } } @@ -1818,7 +1818,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, } break; case Item::REAL_ITEM: - *((double*) to) = arguments[i]->val(); + *((double*) to)= arguments[i]->val_real(); if (!arguments[i]->null_value) { f_args.args[i]=to; @@ -1885,7 +1885,7 @@ bool udf_handler::get_arguments() } break; case REAL_RESULT: - *((double*) to) = args[i]->val(); + *((double*) to)= args[i]->val_real(); if (!args[i]->null_value) { f_args.args[i]=to; @@ -1940,7 +1940,7 @@ String *udf_handler::val_str(String *str,String *save_str) -double Item_func_udf_float::val() +double Item_func_udf_float::val_real() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_udf_float::val"); @@ -1953,7 +1953,7 @@ double Item_func_udf_float::val() String *Item_func_udf_float::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals,&my_charset_bin); @@ -2374,7 +2374,7 @@ longlong Item_func_benchmark::val_int() { switch (args[0]->result_type()) { case REAL_RESULT: - (void) args[0]->val(); + (void) args[0]->val_real(); break; case INT_RESULT: (void) args[0]->val_int(); @@ -2658,7 +2658,7 @@ Item_func_set_user_var::check() switch (cached_result_type) { case REAL_RESULT: { - save_result.vreal= args[0]->val(); + save_result.vreal= args[0]->val_real(); break; } case INT_RESULT: @@ -2739,7 +2739,7 @@ Item_func_set_user_var::update() } -double Item_func_set_user_var::val() +double Item_func_set_user_var::val_real() { DBUG_ASSERT(fixed == 1); check(); @@ -2795,7 +2795,7 @@ Item_func_get_user_var::val_str(String *str) } -double Item_func_get_user_var::val() +double Item_func_get_user_var::val_real() { DBUG_ASSERT(fixed == 1); if (!var_entry) @@ -3266,7 +3266,7 @@ bool Item_func_match::eq(const Item *item, bool binary_cmp) const } -double Item_func_match::val() +double Item_func_match::val_real() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_func_match::val"); diff --git a/sql/item_func.h b/sql/item_func.h index 602b77ae956..03df78d721d 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -165,7 +165,8 @@ public: Item_real_func(Item *a,Item *b) :Item_func(a,b) {} Item_real_func(List &list) :Item_func(list) {} String *val_str(String*str); - longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) val_real(); } enum Item_result result_type () const { return REAL_RESULT; } void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); } }; @@ -179,10 +180,11 @@ public: Item_num_func(Item *a) :Item_func(a),hybrid_type(REAL_RESULT) {} Item_num_func(Item *a,Item *b) :Item_func(a,b),hybrid_type(REAL_RESULT) {} String *val_str(String*str); - longlong val_int() { DBUG_ASSERT(fixed == 1); return (longlong) val(); } + longlong val_int() + { DBUG_ASSERT(fixed == 1); return (longlong) val_real(); } enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); } - bool is_null() { (void) val(); return null_value; } + bool is_null() { (void) val_real(); return null_value; } }; @@ -197,7 +199,7 @@ class Item_num_op :public Item_func enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); find_num_type(); } void find_num_type(void); - bool is_null() { (void) val(); return null_value; } + bool is_null() { (void) val_real(); return null_value; } }; @@ -210,7 +212,7 @@ public: Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; } Item_int_func(List &list) :Item_func(list) { max_length=21; } Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {} - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() {} @@ -222,9 +224,9 @@ class Item_func_signed :public Item_int_func public: Item_func_signed(Item *a) :Item_int_func(a) {} const char *func_name() const { return "cast_as_signed"; } - double val() + double val_real() { - double tmp= args[0]->val(); + double tmp= args[0]->val_real(); null_value= args[0]->null_value; return tmp; } @@ -256,7 +258,7 @@ class Item_func_plus :public Item_num_op public: Item_func_plus(Item *a,Item *b) :Item_num_op(a,b) {} const char *func_name() const { return "+"; } - double val(); + double val_real(); longlong val_int(); }; @@ -265,7 +267,7 @@ class Item_func_minus :public Item_num_op public: Item_func_minus(Item *a,Item *b) :Item_num_op(a,b) {} const char *func_name() const { return "-"; } - double val(); + double val_real(); longlong val_int(); void fix_length_and_dec(); }; @@ -276,7 +278,7 @@ class Item_func_mul :public Item_num_op public: Item_func_mul(Item *a,Item *b) :Item_num_op(a,b) {} const char *func_name() const { return "*"; } - double val(); + double val_real(); longlong val_int(); }; @@ -285,7 +287,7 @@ class Item_func_div :public Item_num_op { public: Item_func_div(Item *a,Item *b) :Item_num_op(a,b) {} - double val(); + double val_real(); longlong val_int(); const char *func_name() const { return "/"; } void fix_length_and_dec(); @@ -297,7 +299,7 @@ class Item_func_int_div :public Item_num_op public: Item_func_int_div(Item *a,Item *b) :Item_num_op(a,b) { hybrid_type=INT_RESULT; } - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } longlong val_int(); const char *func_name() const { return "DIV"; } void fix_length_and_dec(); @@ -308,7 +310,7 @@ class Item_func_mod :public Item_num_op { public: Item_func_mod(Item *a,Item *b) :Item_num_op(a,b) {} - double val(); + double val_real(); longlong val_int(); const char *func_name() const { return "%"; } void fix_length_and_dec(); @@ -319,7 +321,7 @@ class Item_func_neg :public Item_num_func { public: Item_func_neg(Item *a) :Item_num_func(a) {} - double val(); + double val_real(); longlong val_int(); const char *func_name() const { return "-"; } void fix_length_and_dec(); @@ -331,7 +333,7 @@ class Item_func_abs :public Item_num_func public: Item_func_abs(Item *a) :Item_num_func(a) {} const char *func_name() const { return "abs"; } - double val(); + double val_real(); longlong val_int(); enum Item_result result_type () const { return args[0]->result_type() == INT_RESULT ? INT_RESULT : REAL_RESULT; } @@ -368,7 +370,7 @@ class Item_func_exp :public Item_dec_func { public: Item_func_exp(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "exp"; } }; @@ -377,7 +379,7 @@ class Item_func_ln :public Item_dec_func { public: Item_func_ln(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "ln"; } }; @@ -387,7 +389,7 @@ class Item_func_log :public Item_dec_func public: Item_func_log(Item *a) :Item_dec_func(a) {} Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {} - double val(); + double val_real(); const char *func_name() const { return "log"; } }; @@ -396,7 +398,7 @@ class Item_func_log2 :public Item_dec_func { public: Item_func_log2(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "log2"; } }; @@ -405,7 +407,7 @@ class Item_func_log10 :public Item_dec_func { public: Item_func_log10(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "log10"; } }; @@ -414,7 +416,7 @@ class Item_func_sqrt :public Item_dec_func { public: Item_func_sqrt(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "sqrt"; } }; @@ -423,7 +425,7 @@ class Item_func_pow :public Item_dec_func { public: Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {} - double val(); + double val_real(); const char *func_name() const { return "pow"; } }; @@ -432,7 +434,7 @@ class Item_func_acos :public Item_dec_func { public: Item_func_acos(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "acos"; } }; @@ -440,7 +442,7 @@ class Item_func_asin :public Item_dec_func { public: Item_func_asin(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "asin"; } }; @@ -449,7 +451,7 @@ class Item_func_atan :public Item_dec_func public: Item_func_atan(Item *a) :Item_dec_func(a) {} Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {} - double val(); + double val_real(); const char *func_name() const { return "atan"; } }; @@ -457,7 +459,7 @@ class Item_func_cos :public Item_dec_func { public: Item_func_cos(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "cos"; } }; @@ -465,7 +467,7 @@ class Item_func_sin :public Item_dec_func { public: Item_func_sin(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "sin"; } }; @@ -473,7 +475,7 @@ class Item_func_tan :public Item_dec_func { public: Item_func_tan(Item *a) :Item_dec_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "tan"; } }; @@ -511,7 +513,7 @@ public: Item_func_round(Item *a,Item *b,bool trunc_arg) :Item_real_func(a,b),truncate(trunc_arg) {} const char *func_name() const { return truncate ? "truncate" : "round"; } - double val(); + double val_real(); void fix_length_and_dec(); }; @@ -522,7 +524,7 @@ class Item_func_rand :public Item_real_func public: Item_func_rand(Item *a) :Item_real_func(a), rand(0) {} Item_func_rand() :Item_real_func() {} - double val(); + double val_real(); const char *func_name() const { return "rand"; } bool const_item() const { return 0; } void update_used_tables(); @@ -546,7 +548,7 @@ class Item_func_units :public Item_real_func public: Item_func_units(char *name_arg,Item *a,double mul_arg,double add_arg) :Item_real_func(a),name(name_arg),mul(mul_arg),add(add_arg) {} - double val(); + double val_real(); const char *func_name() const { return name; } void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); } }; @@ -560,7 +562,7 @@ class Item_func_min_max :public Item_func public: Item_func_min_max(List &list,int cmp_sign_arg) :Item_func(list), cmp_type(INT_RESULT), cmp_sign(cmp_sign_arg) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *); void fix_length_and_dec(); @@ -799,8 +801,11 @@ class Item_func_udf_float :public Item_udf_func Item_func_udf_float(udf_func *udf_arg, List &list) :Item_udf_func(udf_arg,list) {} longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) Item_func_udf_float::val(); } - double val(); + { + DBUG_ASSERT(fixed == 1); + return (longlong) Item_func_udf_float::val_real(); + } + double val_real(); String *val_str(String *str); void fix_length_and_dec() { fix_num_length_and_dec(); } }; @@ -813,7 +818,7 @@ public: Item_func_udf_int(udf_func *udf_arg, List &list) :Item_udf_func(udf_arg,list) {} longlong val_int(); - double val() { return (double) Item_func_udf_int::val_int(); } + double val_real() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() { decimals=0; max_length=21; } @@ -827,7 +832,7 @@ public: Item_func_udf_str(udf_func *udf_arg, List &list) :Item_udf_func(udf_arg,list) {} String *val_str(String *); - double val() + double val_real() { int err; String *res; res=val_str(&str_value); @@ -850,7 +855,7 @@ class Item_func_udf_float :public Item_real_func public: Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {} Item_func_udf_float(udf_func *udf_arg, List &list) :Item_real_func(list) {} - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } }; @@ -870,7 +875,7 @@ public: Item_func_udf_str(udf_func *udf_arg, List &list) :Item_func(list) {} String *val_str(String *) { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - double val() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); null_value= 1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { maybe_null=1; max_length=0; } @@ -945,7 +950,7 @@ public: Item_func_set_user_var(LEX_STRING a,Item *b) :Item_func(b), cached_result_type(INT_RESULT), name(a) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); bool update_hash(void *ptr, uint length, enum Item_result type, @@ -971,7 +976,7 @@ public: Item_func(), name(a) {} enum Functype functype() const { return GUSERVAR_FUNC; } LEX_STRING get_name() { return name; } - double val(); + double val_real(); longlong val_int(); String *val_str(String* str); void fix_length_and_dec(); @@ -1044,8 +1049,8 @@ public: bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); bool eq(const Item *, bool binary_cmp) const; /* The following should be safe, even if we compare doubles */ - longlong val_int() { DBUG_ASSERT(fixed == 1); return val()!=0.0; } - double val(); + longlong val_int() { DBUG_ASSERT(fixed == 1); return val_real() != 0.0; } + double val_real(); void print(String *str); bool fix_index(); @@ -1134,10 +1139,10 @@ public: longlong val_int() { - return (longlong)Item_func_sp::val(); + return (longlong)Item_func_sp::val_real(); } - double val() + double val_real() { Item *it; double d; @@ -1147,7 +1152,7 @@ public: null_value= 1; return 0.0; } - d= it->val(); + d= it->val_real(); null_value= it->null_value; return d; } diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 7c3319bbfea..163260f6428 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -320,8 +320,8 @@ err: String *Item_func_point::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double x= args[0]->val(); - double y= args[1]->val(); + double x= args[0]->val_real(); + double y= args[1]->val_real(); if ((null_value= (args[0]->null_value || args[1]->null_value || @@ -628,7 +628,7 @@ longlong Item_func_numpoints::val_int() } -double Item_func_x::val() +double Item_func_x::val_real() { DBUG_ASSERT(fixed == 1); double res= 0.0; // In case of errors @@ -645,7 +645,7 @@ double Item_func_x::val() } -double Item_func_y::val() +double Item_func_y::val_real() { DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors @@ -662,7 +662,7 @@ double Item_func_y::val() } -double Item_func_area::val() +double Item_func_area::val_real() { DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors @@ -679,7 +679,7 @@ double Item_func_area::val() return res; } -double Item_func_glength::val() +double Item_func_glength::val_real() { DBUG_ASSERT(fixed == 1); double res= 0; // In case of errors diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 79e4f804a04..e19036cc982 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -263,7 +263,7 @@ class Item_func_x: public Item_real_func String value; public: Item_func_x(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "x"; } }; @@ -273,7 +273,7 @@ class Item_func_y: public Item_real_func String value; public: Item_func_y(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "y"; } }; @@ -316,7 +316,7 @@ class Item_func_area: public Item_real_func String value; public: Item_func_area(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "area"; } }; @@ -326,7 +326,7 @@ class Item_func_glength: public Item_real_func String value; public: Item_func_glength(Item *a): Item_real_func(a) {} - double val(); + double val_real(); const char *func_name() const { return "glength"; } }; diff --git a/sql/item_row.h b/sql/item_row.h index ef5856dcdd3..64bd5cbbb44 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -41,7 +41,7 @@ public: { illegal_method_call((const char*)"make_field"); }; - double val() + double val_real() { illegal_method_call((const char*)"val"); return 0; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 889b00eb6a0..2fcb64ce9d6 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -59,7 +59,7 @@ uint nr_of_decimals(const char *str) return 0; } -double Item_str_func::val() +double Item_str_func::val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -1629,7 +1629,7 @@ Item_func_format::Item_func_format(Item *org,int dec) :Item_str_func(org) String *Item_func_format::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr =args[0]->val(); + double nr= args[0]->val_real(); uint32 diff,length,str_length; uint dec; if ((null_value=args[0]->null_value)) @@ -1697,14 +1697,14 @@ void Item_func_elt::fix_length_and_dec() } -double Item_func_elt::val() +double Item_func_elt::val_real() { DBUG_ASSERT(fixed == 1); uint tmp; null_value=1; if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count) return 0.0; - double result= args[tmp]->val(); + double result= args[tmp]->val_real(); null_value= args[tmp]->null_value; return result; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index afc4b9da0a1..647cf022d79 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -32,7 +32,7 @@ public: Item_str_func(Item *a,Item *b,Item *c,Item *d, Item* e) :Item_func(a,b,c,d,e) {decimals=NOT_FIXED_DEC; } Item_str_func(List &list) :Item_func(list) {decimals=NOT_FIXED_DEC; } longlong val_int(); - double val(); + double val_real(); enum Item_result result_type () const { return STRING_RESULT; } void left_right_max_length(); }; @@ -377,7 +377,7 @@ class Item_func_elt :public Item_str_func { public: Item_func_elt(List &list) :Item_str_func(list) {} - double val(); + double val_real(); longlong val_int(); String *val_str(String *str); void fix_length_and_dec(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index f426f14a25f..7190fe3d625 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -441,13 +441,13 @@ void Item_singlerow_subselect::bring_value() exec(); } -double Item_singlerow_subselect::val() +double Item_singlerow_subselect::val_real() { DBUG_ASSERT(fixed == 1); if (!exec() && !value->null_value) { null_value= 0; - return value->val(); + return value->val_real(); } else { @@ -565,7 +565,7 @@ void Item_exists_subselect::fix_length_and_dec() max_columns= engine->cols(); } -double Item_exists_subselect::val() +double Item_exists_subselect::val_real() { DBUG_ASSERT(fixed == 1); if (exec()) @@ -599,7 +599,7 @@ String *Item_exists_subselect::val_str(String *str) return str; } -double Item_in_subselect::val() +double Item_in_subselect::val_real() { DBUG_ASSERT(fixed == 1); if (exec()) diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 6efb9052115..2e25677d617 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -134,7 +134,7 @@ public: void reset(); trans_res select_transformer(JOIN *join); void store(uint i, Item* item); - double val(); + double val_real(); longlong val_int (); String *val_str (String *); enum Item_result result_type() const; @@ -179,7 +179,7 @@ public: enum Item_result result_type() const { return INT_RESULT;} longlong val_int(); - double val(); + double val_real(); String *val_str(String*); void fix_length_and_dec(); void print(String *str); @@ -224,7 +224,7 @@ public: Comp_creator *func); trans_res row_value_transformer(JOIN * join); longlong val_int(); - double val(); + double val_real(); String *val_str(String*); void top_level_item() { abort_on_null=1; } bool test_limit(st_select_lex_unit *unit); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 72c85e2dd40..4a5278a87d4 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -143,7 +143,7 @@ String * Item_sum_num::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; str->set(nr,decimals, &my_charset_bin); @@ -267,14 +267,14 @@ void Item_sum_sum::clear() bool Item_sum_sum::add() { - sum+=args[0]->val(); + sum+= args[0]->val_real(); if (!args[0]->null_value) null_value= 0; return 0; } -double Item_sum_sum::val() +double Item_sum_sum::val_real() { DBUG_ASSERT(fixed == 1); return sum; @@ -359,8 +359,8 @@ void Item_sum_sum_distinct::clear() bool Item_sum_sum_distinct::add() { - /* args[0]->val() may reset args[0]->null_value */ - double val= args[0]->val(); + /* args[0]->val_real() may reset args[0]->null_value */ + double val= args[0]->val_real(); if (!args[0]->null_value) { DBUG_ASSERT(tree); @@ -383,7 +383,7 @@ static int sum_sum_distinct(void *element, element_count num_of_dups, C_MODE_END -double Item_sum_sum_distinct::val() +double Item_sum_sum_distinct::val_real() { /* We don't have a tree only if 'setup()' hasn't been called; @@ -456,7 +456,7 @@ void Item_sum_avg::clear() bool Item_sum_avg::add() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value) { sum+=nr; @@ -465,7 +465,7 @@ bool Item_sum_avg::add() return 0; } -double Item_sum_avg::val() +double Item_sum_avg::val_real() { DBUG_ASSERT(fixed == 1); if (!count) @@ -482,10 +482,10 @@ double Item_sum_avg::val() Standard deviation */ -double Item_sum_std::val() +double Item_sum_std::val_real() { DBUG_ASSERT(fixed == 1); - double tmp= Item_sum_variance::val(); + double tmp= Item_sum_variance::val_real(); return tmp <= 0.0 ? 0.0 : sqrt(tmp); } @@ -513,7 +513,7 @@ void Item_sum_variance::clear() bool Item_sum_variance::add() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value) { sum+=nr; @@ -523,7 +523,7 @@ bool Item_sum_variance::add() return 0; } -double Item_sum_variance::val() +double Item_sum_variance::val_real() { DBUG_ASSERT(fixed == 1); if (!count) @@ -540,7 +540,7 @@ double Item_sum_variance::val() void Item_sum_variance::reset_field() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); char *res=result_field->ptr; if (args[0]->null_value) @@ -565,7 +565,7 @@ void Item_sum_variance::update_field() float8get(old_sqr, res+sizeof(double)); field_count=sint8korr(res+sizeof(double)*2); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { old_nr+=nr; @@ -587,7 +587,7 @@ void Item_sum_hybrid::clear() null_value= 1; } -double Item_sum_hybrid::val() +double Item_sum_hybrid::val_real() { DBUG_ASSERT(fixed == 1); int err; @@ -620,7 +620,7 @@ longlong Item_sum_hybrid::val_int() return 0; if (hybrid_type == INT_RESULT) return sum_int; - return (longlong) Item_sum_hybrid::val(); + return (longlong) Item_sum_hybrid::val_real(); } @@ -696,7 +696,7 @@ bool Item_sum_min::add() break; case REAL_RESULT: { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value && (null_value || nr < sum)) { sum=nr; @@ -749,7 +749,7 @@ bool Item_sum_max::add() break; case REAL_RESULT: { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (!args[0]->null_value && (null_value || nr > sum)) { sum=nr; @@ -829,7 +829,7 @@ bool Item_sum_and::add() void Item_sum_num::reset_field() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); char *res=result_field->ptr; if (maybe_null) @@ -883,7 +883,7 @@ void Item_sum_hybrid::reset_field() } else // REAL_RESULT { - double nr=args[0]->val(); + double nr= args[0]->val_real(); if (maybe_null) { @@ -902,7 +902,7 @@ void Item_sum_hybrid::reset_field() void Item_sum_sum::reset_field() { - double nr=args[0]->val(); // Nulls also return 0 + double nr= args[0]->val_real(); // Nulls also return 0 float8store(result_field->ptr,nr); if (args[0]->null_value) result_field->set_null(); @@ -930,7 +930,7 @@ void Item_sum_count::reset_field() void Item_sum_avg::reset_field() { - double nr=args[0]->val(); + double nr= args[0]->val_real(); char *res=result_field->ptr; if (args[0]->null_value) @@ -968,7 +968,7 @@ void Item_sum_sum::update_field() char *res=result_field->ptr; float8get(old_nr,res); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { old_nr+=nr; @@ -1005,7 +1005,7 @@ void Item_sum_avg::update_field() float8get(old_nr,res); field_count=sint8korr(res+sizeof(double)); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { old_nr+=nr; @@ -1051,7 +1051,7 @@ Item_sum_hybrid::min_max_update_real_field() double nr,old_nr; old_nr=result_field->val_real(); - nr=args[0]->val(); + nr= args[0]->val_real(); if (!args[0]->null_value) { if (result_field->is_null(0) || @@ -1103,7 +1103,7 @@ Item_avg_field::Item_avg_field(Item_sum_avg *item) } -double Item_avg_field::val() +double Item_avg_field::val_real() { // fix_fields() never calls for this Item double nr; @@ -1124,7 +1124,7 @@ double Item_avg_field::val() String *Item_avg_field::val_str(String *str) { // fix_fields() never calls for this Item - double nr=Item_avg_field::val(); + double nr= Item_avg_field::val_real(); if (null_value) return 0; str->set(nr,decimals, &my_charset_bin); @@ -1136,10 +1136,10 @@ Item_std_field::Item_std_field(Item_sum_std *item) { } -double Item_std_field::val() +double Item_std_field::val_real() { // fix_fields() never calls for this Item - double tmp= Item_variance_field::val(); + double tmp= Item_variance_field::val_real(); return tmp <= 0.0 ? 0.0 : sqrt(tmp); } @@ -1152,7 +1152,7 @@ Item_variance_field::Item_variance_field(Item_sum_variance *item) maybe_null=1; } -double Item_variance_field::val() +double Item_variance_field::val_real() { // fix_fields() never calls for this Item double sum,sum_sqr; @@ -1175,7 +1175,7 @@ double Item_variance_field::val() String *Item_variance_field::val_str(String *str) { // fix_fields() never calls for this Item - double nr=val(); + double nr= val_real(); if (null_value) return 0; str->set(nr,decimals, &my_charset_bin); @@ -1553,7 +1553,7 @@ Item *Item_sum_udf_float::copy_or_same(THD* thd) return new (thd->mem_root) Item_sum_udf_float(thd, this); } -double Item_sum_udf_float::val() +double Item_sum_udf_float::val_real() { DBUG_ASSERT(fixed == 1); DBUG_ENTER("Item_sum_udf_float::val"); @@ -1565,7 +1565,7 @@ double Item_sum_udf_float::val() String *Item_sum_udf_float::val_str(String *str) { DBUG_ASSERT(fixed == 1); - double nr=val(); + double nr= val_real(); if (null_value) return 0; /* purecov: inspected */ str->set(nr,decimals, &my_charset_bin); diff --git a/sql/item_sum.h b/sql/item_sum.h index cede5a1e02e..85651c80288 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -107,7 +107,10 @@ public: Item_sum_num(THD *thd, Item_sum_num *item) :Item_sum(thd, item) {} bool fix_fields(THD *, TABLE_LIST *, Item **); longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) val(); } /* Real as default */ + { + DBUG_ASSERT(fixed == 1); + return (longlong) val_real(); /* Real as default */ + } String *val_str(String*str); void reset_field(); }; @@ -119,7 +122,7 @@ public: Item_sum_int(Item *item_par) :Item_sum_num(item_par) {} Item_sum_int(List &list) :Item_sum_num(list) {} Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {} - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } void fix_length_and_dec() @@ -139,7 +142,7 @@ class Item_sum_sum :public Item_sum_num enum Sumfunctype sum_func () const {return SUM_FUNC;} void clear(); bool add(); - double val(); + double val_real(); void reset_field(); void update_field(); void no_rows_in_result() {} @@ -169,7 +172,7 @@ public: bool setup(THD *thd); void clear(); bool add(); - double val(); + double val_real(); inline void add(double val) { sum+= val; } enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; } @@ -302,8 +305,9 @@ public: Field *field; Item_avg_field(Item_sum_avg *item); enum Type type() const { return FIELD_AVG_ITEM; } - double val(); - longlong val_int() { /* can't be fix_fields()ed */ return (longlong) val(); } + double val_real(); + longlong val_int() + { /* can't be fix_fields()ed */ return (longlong) val_real(); } bool is_null() { (void) val_int(); return null_value; } String *val_str(String*); enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } @@ -329,7 +333,7 @@ class Item_sum_avg :public Item_sum_num enum Sumfunctype sum_func () const {return AVG_FUNC;} void clear(); bool add(); - double val(); + double val_real(); void reset_field(); void update_field(); Item *result_item(Field *field) @@ -347,8 +351,9 @@ public: Field *field; Item_variance_field(Item_sum_variance *item); enum Type type() const {return FIELD_VARIANCE_ITEM; } - double val(); - longlong val_int() { /* can't be fix_fields()ed */ return (longlong) val(); } + double val_real(); + longlong val_int() + { /* can't be fix_fields()ed */ return (longlong) val_real(); } String *val_str(String*); bool is_null() { (void) val_int(); return null_value; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } @@ -386,7 +391,7 @@ class Item_sum_variance : public Item_sum_num enum Sumfunctype sum_func () const { return VARIANCE_FUNC; } void clear(); bool add(); - double val(); + double val_real(); void reset_field(); void update_field(); Item *result_item(Field *field) @@ -403,7 +408,7 @@ class Item_std_field :public Item_variance_field public: Item_std_field(Item_sum_std *item); enum Type type() const { return FIELD_STD_ITEM; } - double val(); + double val_real(); }; /* @@ -418,7 +423,7 @@ class Item_sum_std :public Item_sum_variance :Item_sum_variance(thd, item) {} enum Sumfunctype sum_func () const { return STD_FUNC; } - double val(); + double val_real(); Item *result_item(Field *field) { return new Item_std_field(this); } const char *func_name() const { return "std"; } @@ -456,7 +461,7 @@ class Item_sum_hybrid :public Item_sum bool const_item() const { return !used_table_cache; } void clear(); - double val(); + double val_real(); longlong val_int(); void reset_field(); String *val_str(String *); @@ -594,8 +599,11 @@ class Item_sum_udf_float :public Item_udf_sum Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_udf_sum(thd, item) {} longlong val_int() - { DBUG_ASSERT(fixed == 1); return (longlong) Item_sum_udf_float::val(); } - double val(); + { + DBUG_ASSERT(fixed == 1); + return (longlong) Item_sum_udf_float::val_real(); + } + double val_real(); String *val_str(String*str); void fix_length_and_dec() { fix_num_length_and_dec(); } Item *copy_or_same(THD* thd); @@ -611,7 +619,7 @@ public: Item_sum_udf_int(THD *thd, Item_sum_udf_int *item) :Item_udf_sum(thd, item) {} longlong val_int(); - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_sum_udf_int::val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } @@ -629,7 +637,7 @@ public: Item_sum_udf_str(THD *thd, Item_sum_udf_str *item) :Item_udf_sum(thd, item) {} String *val_str(String *); - double val() + double val_real() { int err; String *res; res=val_str(&str_value); @@ -657,7 +665,7 @@ class Item_sum_udf_float :public Item_sum_num Item_sum_udf_float(THD *thd, Item_sum_udf_float *item) :Item_sum_num(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } void clear() {} bool add() { return 0; } void update_field() {} @@ -673,7 +681,7 @@ public: :Item_sum_num(thd, item) {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } longlong val_int() { DBUG_ASSERT(fixed == 1); return 0; } - double val() { DBUG_ASSERT(fixed == 1); return 0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0; } void clear() {} bool add() { return 0; } void update_field() {} @@ -689,7 +697,7 @@ public: :Item_sum_num(thd, item) {} String *val_str(String *) { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } - double val() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); null_value=1; return 0.0; } longlong val_int() { DBUG_ASSERT(fixed == 1); null_value=1; return 0; } enum Item_result result_type () const { return STRING_RESULT; } void fix_length_and_dec() { maybe_null=1; max_length=0; } @@ -761,7 +769,7 @@ class Item_func_group_concat : public Item_sum bool setup(THD *thd); void make_unique(); virtual void update_field() {} - double val() + double val_real() { String *res; res=val_str(&str_value); return res ? my_atof(res->c_ptr()) : 0.0; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 694f2dc583c..dccba7f52b1 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -88,7 +88,7 @@ class Item_func_month :public Item_func public: Item_func_month(Item *a) :Item_func(a) {} longlong val_int(); - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); } String *val_str(String *str) { @@ -250,7 +250,7 @@ public: Item_func_weekday(Item *a,bool type_arg) :Item_func(a), odbc_type(type_arg) {} longlong val_int(); - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } String *val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -326,7 +326,7 @@ public: enum_field_types field_type() const { return MYSQL_TYPE_DATE; } String *val_str(String *str); longlong val_int(); - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } const char *func_name() const { return "date"; } void fix_length_and_dec() { @@ -369,7 +369,7 @@ public: Item_func_curtime(Item *a) :Item_func(a) {} enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; } - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } String *val_str(String *str); void fix_length_and_dec(); @@ -452,7 +452,7 @@ public: Item_func_now() :Item_date_func() {} Item_func_now(Item *a) :Item_date_func(a) {} enum Item_result result_type () const { return STRING_RESULT; } - double val() { DBUG_ASSERT(fixed == 1); return (double) value; } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } int save_in_field(Field *to, bool no_conversions); String *val_str(String *str); @@ -512,7 +512,7 @@ class Item_func_from_unixtime :public Item_date_func THD *thd; public: Item_func_from_unixtime(Item *a) :Item_date_func(a) {} - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_func_from_unixtime::val_int(); @@ -552,7 +552,7 @@ class Item_func_convert_tz :public Item_date_func Item_func_convert_tz(Item *a, Item *b, Item *c): Item_date_func(a, b, c) {} longlong val_int(); - double val() { return (double) val_int(); } + double val_real() { return (double) val_int(); } String *val_str(String *str); const char *func_name() const { return "convert_tz"; } bool fix_fields(THD *, struct st_table_list *, Item **); @@ -565,7 +565,7 @@ class Item_func_sec_to_time :public Item_str_func { public: Item_func_sec_to_time(Item *item) :Item_str_func(item) {} - double val() + double val_real() { DBUG_ASSERT(fixed == 1); return (double) Item_func_sec_to_time::val_int(); @@ -615,7 +615,7 @@ public: const char *func_name() const { return "date_add_interval"; } void fix_length_and_dec(); enum_field_types field_type() const { return cached_field_type; } - double val() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } + double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } longlong val_int(); bool get_date(TIME *res, uint fuzzy_date); void print(String *str); diff --git a/sql/item_uniq.h b/sql/item_uniq.h index 5582537bdbb..d21e2e2a619 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -27,7 +27,7 @@ class Item_func_unique_users :public Item_real_func public: Item_func_unique_users(Item *name_arg,int start,int end,List &list) :Item_real_func(list) {} - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } void fix_length_and_dec() { decimals=0; max_length=6; } void print(String *str) { str->append("0.0", 3); } }; @@ -40,7 +40,7 @@ public: :Item_sum_num(item_arg) {} Item_sum_unique_users(THD *thd, Item_sum_unique_users *item) :Item_sum_num(thd, item) {} - double val() { DBUG_ASSERT(fixed == 1); return 0.0; } + double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; } enum Sumfunctype sum_func () const {return UNIQUE_USERS_FUNC;} void clear() {} bool add() { return 0; } diff --git a/sql/procedure.h b/sql/procedure.h index 5365b2e1102..160777967ff 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -60,7 +60,7 @@ public: void set(longlong nr) { value=(double) nr; } void set(const char *str,uint length,CHARSET_INFO *cs) { int err; value=my_strntod(cs,(char*) str,length,(char**)0,&err); } - double val() { return value; } + double val_real() { return value; } longlong val_int() { return (longlong) value; } String *val_str(String *s) { s->set(value,decimals,default_charset()); return s; } unsigned int size_of() { return sizeof(*this);} @@ -78,7 +78,7 @@ public: void set(longlong nr) { value=nr; } void set(const char *str,uint length, CHARSET_INFO *cs) { int err; value=my_strntoll(cs,str,length,10,NULL,&err); } - double val() { return (double) value; } + double val_real() { return (double) value; } longlong val_int() { return value; } String *val_str(String *s) { s->set(value, default_charset()); return s; } unsigned int size_of() { return sizeof(*this);} @@ -96,7 +96,7 @@ public: void set(longlong nr) { str_value.set(nr, default_charset()); } void set(const char *str, uint length, CHARSET_INFO *cs) { str_value.copy(str,length,cs); } - double val() + double val_real() { int err; CHARSET_INFO *cs=str_value.charset(); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 47e3952bcdd..a18bc2abe39 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -134,7 +134,7 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) } case REAL_RESULT: { - double d= it->val(); + double d= it->val_real(); if (it->null_value) { @@ -148,7 +148,7 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) uint8 decimals= it->decimals; uint32 max_length= it->max_length; DBUG_PRINT("info", ("REAL_RESULT: %g", d)); - it= new Item_real(it->val()); + it= new Item_real(it->val_real()); it->decimals= decimals; it->max_length= max_length; } diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 1e0aebbc1ec..2259d3bead8 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -78,7 +78,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, { // first parameter if ((*param->item)->type() != Item::INT_ITEM || - (*param->item)->val() < 0) + (*param->item)->val_real() < 0) { delete pc; my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); @@ -93,7 +93,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, } // second parameter if ((*param->item)->type() != Item::INT_ITEM || - (*param->item)->val() < 0) + (*param->item)->val_real() < 0) { delete pc; my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); @@ -102,7 +102,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, pc->max_treemem = (uint) (*param->item)->val_int(); } else if ((*param->item)->type() != Item::INT_ITEM || - (*param->item)->val() < 0) + (*param->item)->val_real() < 0) { delete pc; my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); @@ -364,7 +364,7 @@ void field_str::add() void field_real::add() { char buff[MAX_FIELD_WIDTH], *ptr, *end; - double num = item->val(); + double num= item->val_real(); uint length, zero_count, decs; TREE_ELEMENT *element; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 15e1cc7e212..8a1b6fae6e7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1345,7 +1345,7 @@ bool select_max_min_finder_subselect::send_data(List &items) bool select_max_min_finder_subselect::cmp_real() { Item *maxmin= ((Item_singlerow_subselect *)item)->el(0); - double val1= cache->val(), val2= maxmin->val(); + double val1= cache->val_real(), val2= maxmin->val_real(); if (fmax) return (cache->null_value && !maxmin->null_value) || (!cache->null_value && !maxmin->null_value && diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 89edc06139c..d07e274b0b7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2936,14 +2936,14 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, Item_func *arg0=(Item_func *)(func->arguments()[0]), *arg1=(Item_func *)(func->arguments()[1]); if (arg1->const_item() && - ((functype == Item_func::GE_FUNC && arg1->val()> 0) || - (functype == Item_func::GT_FUNC && arg1->val()>=0)) && + ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) || + (functype == Item_func::GT_FUNC && arg1->val_real() >=0)) && arg0->type() == Item::FUNC_ITEM && arg0->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg0; else if (arg0->const_item() && - ((functype == Item_func::LE_FUNC && arg0->val()> 0) || - (functype == Item_func::LT_FUNC && arg0->val()>=0)) && + ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) || + (functype == Item_func::LT_FUNC && arg0->val_real() >=0)) && arg1->type() == Item::FUNC_ITEM && arg1->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg1; -- cgit v1.2.1 From c157d1199310d0b14fc63e9855e2e156273a6a42 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 21:57:55 +0300 Subject: Cleanup in sql_acl.cc: thd->lex ->lex sql/sql_acl.cc: Cleanup: we want to synonim thd->lex on stack, as we use it often in replace_user_table. --- sql/sql_acl.cc | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3e3642dd0bd..9e571e4b84c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1528,6 +1528,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, uint password_len= 0; char what= (revoke_grant) ? 'N' : 'Y'; DBUG_ENTER("replace_user_table"); + LEX *lex= thd->lex; safe_mutex_assert_owner(&acl_cache->lock); if (combo.password.str && combo.password.str[0]) @@ -1600,8 +1601,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, 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); - else if (!rights && !revoke_grant && thd->lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && - !thd->lex->mqh.bits) + else if (!rights && !revoke_grant && + lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && !lex->mqh.bits) { DBUG_RETURN(0); } @@ -1624,7 +1625,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (table->fields >= 31) /* From 4.0.0 we have more fields */ { /* We write down SSL related ACL stuff */ - switch (thd->lex->ssl_type) { + switch (lex->ssl_type) { case SSL_TYPE_ANY: table->field[24]->store("ANY",3, &my_charset_latin1); table->field[25]->store("", 0, &my_charset_latin1); @@ -1642,15 +1643,15 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, table->field[25]->store("", 0, &my_charset_latin1); table->field[26]->store("", 0, &my_charset_latin1); table->field[27]->store("", 0, &my_charset_latin1); - if (thd->lex->ssl_cipher) - table->field[25]->store(thd->lex->ssl_cipher, - strlen(thd->lex->ssl_cipher), &my_charset_latin1); - if (thd->lex->x509_issuer) - table->field[26]->store(thd->lex->x509_issuer, - strlen(thd->lex->x509_issuer), &my_charset_latin1); - if (thd->lex->x509_subject) - table->field[27]->store(thd->lex->x509_subject, - strlen(thd->lex->x509_subject), &my_charset_latin1); + if (lex->ssl_cipher) + table->field[25]->store(lex->ssl_cipher, + strlen(lex->ssl_cipher), &my_charset_latin1); + if (lex->x509_issuer) + table->field[26]->store(lex->x509_issuer, + strlen(lex->x509_issuer), &my_charset_latin1); + if (lex->x509_subject) + table->field[27]->store(lex->x509_subject, + strlen(lex->x509_subject), &my_charset_latin1); break; case SSL_TYPE_NOT_SPECIFIED: break; @@ -1662,7 +1663,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, break; } - USER_RESOURCES mqh= thd->lex->mqh; + USER_RESOURCES mqh= lex->mqh; if (mqh.bits & 1) table->field[28]->store((longlong) mqh.questions); if (mqh.bits & 2) @@ -1704,19 +1705,19 @@ end: if (old_row_exists) acl_update_user(combo.user.str, combo.host.str, combo.password.str, password_len, - thd->lex->ssl_type, - thd->lex->ssl_cipher, - thd->lex->x509_issuer, - thd->lex->x509_subject, - &thd->lex->mqh, + lex->ssl_type, + lex->ssl_cipher, + lex->x509_issuer, + lex->x509_subject, + &lex->mqh, rights); else acl_insert_user(combo.user.str, combo.host.str, password, password_len, - thd->lex->ssl_type, - thd->lex->ssl_cipher, - thd->lex->x509_issuer, - thd->lex->x509_subject, - &thd->lex->mqh, + lex->ssl_type, + lex->ssl_cipher, + lex->x509_issuer, + lex->x509_subject, + &lex->mqh, rights); } DBUG_RETURN(error); -- cgit v1.2.1 From a6e1436f4a02a4b703c1a4edfebc84604419ed57 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 22:16:46 +0300 Subject: Cleanup: thd->lex->select_lex -> select_lex (sql_delete.cc) sql/sql_delete.cc: Cleanup: thd->lex->select_lex -> select_lex --- sql/sql_delete.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8bdf19195f3..b8f560b3ef2 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -39,6 +39,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, bool using_limit=limit != HA_POS_ERROR; bool transactional_table, log_delayed, safe_update, const_cond; ha_rows deleted; + SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_delete"); if ((error= open_and_lock_tables(thd, table_list))) @@ -60,7 +61,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, } if (thd->lex->duplicates == DUP_IGNORE) - thd->lex->select_lex.no_error= 1; + select_lex->no_error= 1; /* Test if the user wants to delete all rows */ if (!using_limit && const_cond && (!conds || conds->val_int()) && @@ -89,7 +90,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if ((select && select->check_quick(thd, safe_update, limit)) || !limit) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); thd->row_count_func= 0; send_ok(thd,0L); DBUG_RETURN(0); // Nothing to delete @@ -102,7 +103,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if (safe_update && !using_limit) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE); DBUG_RETURN(1); } @@ -124,8 +125,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); - if (thd->lex->select_lex.setup_ref_array(thd, order->elements) || - setup_order(thd, thd->lex->select_lex.ref_pointer_array, &tables, + if (select_lex->setup_ref_array(thd, order->elements) || + setup_order(thd, select_lex->ref_pointer_array, &tables, fields, all_fields, (ORDER*) order->first) || !(sortorder=make_unireg_sortorder((ORDER*) order->first, &length)) || (table->sort.found_records = filesort(thd, table, sortorder, length, @@ -134,7 +135,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, == HA_POS_ERROR) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); DBUG_RETURN(-1); // This will force out message } /* @@ -149,12 +150,12 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if (select && select->quick && select->quick->reset()) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); DBUG_RETURN(-1); // This will force out message } init_read_record(&info,thd,table,select,1,1); deleted=0L; - init_ftfuncs(thd, &thd->lex->select_lex, 1); + init_ftfuncs(thd, select_lex, 1); thd->proc_info="updating"; while (!(error=info.read_record(&info)) && !thd->killed && !thd->net.report_error) @@ -252,7 +253,7 @@ cleanup: mysql_unlock_tables(thd, thd->lock); thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); if (error >= 0 || thd->net.report_error) send_error(thd,thd->killed_errno()); else -- cgit v1.2.1 From 7161b21fedf018f31e93229570df16ada028eb2d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 22:37:48 +0300 Subject: Few more places with thd->lex replaced with lex (mysql_update, check_simple_select). This change was inspired by Monty in December 2003 when thd->lex became a pointer in 4.1. sql/sql_parse.cc: Few more places with thd->lex replaced with lex. sql/sql_update.cc: Few more places with thd->lex replaced with lex. --- sql/sql_parse.cc | 7 ++++--- sql/sql_update.cc | 15 ++++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a14a3da8391..1adc40e8446 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5865,11 +5865,12 @@ static bool append_file_to_dir(THD *thd, const char **filename_ptr, bool check_simple_select() { THD *thd= current_thd; - if (thd->lex->current_select != &thd->lex->select_lex) + LEX *lex= thd->lex; + if (lex->current_select != &lex->select_lex) { char command[80]; - strmake(command, thd->lex->yylval->symbol.str, - min(thd->lex->yylval->symbol.length, sizeof(command)-1)); + strmake(command, lex->yylval->symbol.str, + min(lex->yylval->symbol.length, sizeof(command)-1)); net_printf(thd, ER_CANT_USE_OPTION_HERE, command); return 1; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 561480bd289..9d382baf155 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -111,6 +111,7 @@ int mysql_update(THD *thd, TABLE *table; SQL_SELECT *select; READ_RECORD info; + SELECT_LEX *select_lex= &thd->lex->select_lex; DBUG_ENTER("mysql_update"); LINT_INIT(used_index); @@ -151,9 +152,9 @@ int mysql_update(THD *thd, table_list->grant.want_privilege= table->grant.want_privilege= want_privilege; #endif { - thd->lex->select_lex.no_wrap_view_item= 1; + select_lex->no_wrap_view_item= 1; res= setup_fields(thd, 0, table_list, fields, 1, 0, 0); - thd->lex->select_lex.no_wrap_view_item= 0; + select_lex->no_wrap_view_item= 0; if (res) DBUG_RETURN(-1); /* purecov: inspected */ } @@ -182,7 +183,7 @@ int mysql_update(THD *thd, #endif if (setup_fields(thd, 0, table_list, values, 0, 0, 0)) { - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); DBUG_RETURN(-1); /* purecov: inspected */ } @@ -193,7 +194,7 @@ int mysql_update(THD *thd, (select && select->check_quick(thd, safe_update, limit)) || !limit) { delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); if (error) { DBUG_RETURN(-1); // Error in where @@ -212,7 +213,7 @@ int mysql_update(THD *thd, goto err; } } - init_ftfuncs(thd, &thd->lex->select_lex, 1); + init_ftfuncs(thd, select_lex, 1); /* Check if we are modifying a key that we are used to search with */ if (select && select->quick) @@ -455,7 +456,7 @@ int mysql_update(THD *thd, thd->lock=0; } - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); if (error >= 0) send_error(thd,thd->killed_errno()); /* purecov: inspected */ else @@ -476,7 +477,7 @@ int mysql_update(THD *thd, err: delete select; - free_underlaid_joins(thd, &thd->lex->select_lex); + free_underlaid_joins(thd, select_lex); if (table->key_read) { table->key_read=0; -- cgit v1.2.1 From aebe9454e24179713fc1fea7690f66e1cd416500 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 23:30:39 +0300 Subject: Rename: send_prepare_results -> check_prepared_statement (sql_prepare.cc) sql/sql_prepare.cc: send_prepare_results -> check_prepared_statement --- sql/sql_prepare.cc | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 1c23162b212..75cfac5f58a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1386,23 +1386,34 @@ static int mysql_test_insert_select(Prepared_statement *stmt, /* - Send the prepare query results back to client + Perform semantic analysis of the parsed tree and send a response packet + to the client. + SYNOPSIS - send_prepare_results() - stmt prepared statement + check_prepared_statement() + stmt prepared statement + + DESCRIPTION + This function + - opens all tables and checks access rights + - validates semantics of statement columns and SQL functions + by calling fix_fields. + RETURN VALUE 0 success 1 error, sent to client */ -static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) -{ + +static int check_prepared_statement(Prepared_statement *stmt, + bool text_protocol) +{ THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX *select_lex= &lex->select_lex; TABLE_LIST *tables; enum enum_sql_command sql_command= lex->sql_command; int res= 0; - DBUG_ENTER("send_prepare_results"); + DBUG_ENTER("check_prepared_statement"); DBUG_PRINT("enter",("command: %d, param_count: %ld", sql_command, stmt->param_count)); @@ -1644,8 +1655,8 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, error= yyparse((void *)thd) || thd->is_fatal_error || thd->net.report_error || init_param_array(stmt); /* - While doing context analysis of the query (in send_prepare_results) we - allocate a lot of additional memory: for open tables, JOINs, derived + While doing context analysis of the query (in check_prepared_statement) + we allocate a lot of additional memory: for open tables, JOINs, derived tables, etc. Let's save a snapshot of current parse tree to the statement and restore original THD. In cases when some tree transformation can be reused on execute, we set again thd->mem_root from @@ -1654,7 +1665,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, thd->restore_backup_item_arena(stmt, &thd->stmt_backup); if (!error) - error= send_prepare_results(stmt, test(name)); + error= check_prepared_statement(stmt, test(name)); /* restore to WAIT_PRIOR: QUERY_PRIOR is set inside alloc_query */ if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1681,7 +1692,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, stmt= NULL; if (thd->net.report_error) send_error(thd); - /* otherwise the error is sent inside yyparse/send_prepare_results */ + /* otherwise the error is sent inside yyparse/check_preapred_statement */ } else { -- cgit v1.2.1 From b19eb67f08d04de3af744097e72023d550329035 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 20:59:03 +0000 Subject: Bug#6123 - GRANT USAGE creates useless mysql.db row Prevent creation of a row which grants no rights Test included mysql-test/r/grant.result: Test for Bug#6123 mysql-test/t/grant.test: Test for Bug#6123 sql/sql_acl.cc: Bug#6123 Prevent creation of useless row --- sql/sql_acl.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index b3bc5a1e4f2..67ca62357ec 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1587,7 +1587,7 @@ static int replace_db_table(TABLE *table, const char *db, goto table_error; /* purecov: deadcode */ } } - else if ((error=table->file->write_row(table->record[0]))) + else if (rights && (error=table->file->write_row(table->record[0]))) { if (error && error != HA_ERR_FOUND_DUPP_KEY) /* purecov: inspected */ goto table_error; /* purecov: deadcode */ @@ -1597,6 +1597,7 @@ static int replace_db_table(TABLE *table, const char *db, if (old_row_exists) acl_update_db(combo.user.str,combo.host.str,db,rights); else + if (rights) acl_insert_db(combo.user.str,combo.host.str,db,rights); table->file->index_end(); DBUG_RETURN(0); -- cgit v1.2.1 From 593c7ce9c2fb6a1410d87b797618b5b1f646f2d6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 Nov 2004 19:01:46 -0800 Subject: Mainly resolving Guilhem's 4.1 patch to 5.0 client/mysqlbinlog.cc: Resolveing merge client/mysqldump.c: resolving merge sql/handler.cc: resolving merge sql/lex.h: resolve merge sql/log.cc: resolving merge sql/log_event.cc: resolving merge sql/sql_parse.cc: resolving merge sql/sql_yacc.yy: resolving merge --- sql/handler.cc | 195 +++- sql/lex.h | 71 +- sql/log.cc | 161 ++-- sql/log_event.cc | 1634 ++++++++++++++++++++++++--------- sql/sql_parse.cc | 1731 +++++++++++++++++++++++++---------- sql/sql_yacc.yy | 2647 ++++++++++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 5066 insertions(+), 1373 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index 5dae7950390..b2acb262763 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -54,11 +54,7 @@ static int NEAR_F delete_file(const char *name,const char *ext,int extflag); -ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, - ha_read_key_count, ha_read_next_count, ha_read_prev_count, - ha_read_first_count, ha_read_last_count, - ha_commit_count, ha_rollback_count, - ha_read_rnd_count, ha_read_rnd_next_count, ha_discover_count; +ulong ha_read_count, ha_discover_count; static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES; @@ -114,7 +110,7 @@ uint known_extensions_id= 0; enum db_type ha_resolve_by_name(const char *name, uint namelen) { - THD *thd=current_thd; + THD *thd= current_thd; if (thd && !my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { return (enum db_type) thd->variables.table_type; } @@ -145,6 +141,7 @@ const char *ha_get_storage_engine(enum db_type db_type) enum db_type ha_checktype(enum db_type database_type) { show_table_type_st *types; + THD *thd= current_thd; for (types= sys_table_types; types->type; types++) { if ((database_type == types->db_type) && @@ -163,12 +160,11 @@ enum db_type ha_checktype(enum db_type database_type) break; } - return - DB_TYPE_UNKNOWN != (enum db_type) current_thd->variables.table_type ? - (enum db_type) current_thd->variables.table_type : - DB_TYPE_UNKNOWN != (enum db_type) global_system_variables.table_type ? - (enum db_type) global_system_variables.table_type : - DB_TYPE_MYISAM; + return ((enum db_type) thd->variables.table_type != DB_TYPE_UNKNOWN ? + (enum db_type) thd->variables.table_type : + (enum db_type) global_system_variables.table_type != + DB_TYPE_UNKNOWN ? + (enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM); } /* ha_checktype */ @@ -565,7 +561,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) thd->variables.tx_isolation=thd->session_tx_isolation; if (operation_done) { - statistic_increment(ha_commit_count,&LOCK_status); + statistic_increment(thd->status_var.ha_commit_count,&LOCK_status); thd->transaction.cleanup(); } if (need_start_waiters) @@ -734,7 +730,7 @@ int ha_rollback_to_savepoint(THD *thd, char *savepoint_name) operation_done=1; #endif if (operation_done) - statistic_increment(ha_rollback_count,&LOCK_status); + statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status); } #endif /* USING_TRANSACTIONS */ @@ -816,10 +812,14 @@ bool ha_flush_logs() int ha_delete_table(enum db_type table_type, const char *path) { + handler *file; char tmp_path[FN_REFLEN]; - handler *file=get_new_handler((TABLE*) 0, table_type); - if (!file) + + /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */ + if (table_type == DB_TYPE_UNKNOWN || + ! (file=get_new_handler((TABLE*) 0, table_type))) return ENOENT; + if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED)) { /* Ensure that table handler get path in lower case */ @@ -948,7 +948,7 @@ int handler::read_first_row(byte * buf, uint primary_key) register int error; DBUG_ENTER("handler::read_first_row"); - statistic_increment(ha_read_first_count,&LOCK_status); + statistic_increment(current_thd->status_var.ha_read_first_count,&LOCK_status); /* If there is very few deleted rows in the table, find the first row by @@ -972,41 +972,163 @@ int handler::read_first_row(byte * buf, uint primary_key) /* - Updates field with field_type NEXT_NUMBER according to following: - if field = 0 change field to the next free key in database. + Generate the next auto-increment number based on increment and offset + + In most cases increment= offset= 1, in which case we get: + 1,2,3,4,5,... + If increment=10 and offset=5 and previous number is 1, we get: + 1,5,15,25,35,... +*/ + +inline ulonglong +next_insert_id(ulonglong nr,struct system_variables *variables) +{ + nr= (((nr+ variables->auto_increment_increment - + variables->auto_increment_offset)) / + (ulonglong) variables->auto_increment_increment); + return (nr* (ulonglong) variables->auto_increment_increment + + variables->auto_increment_offset); +} + + +/* + Updates columns with type NEXT_NUMBER if: + + - If column value is set to NULL (in which case + auto_increment_field_not_null is 0) + - If column is set to 0 and (sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) is not + set. In the future we will only set NEXT_NUMBER fields if one sets them + to NULL (or they are not included in the insert list). + + + There are two different cases when the above is true: + + - thd->next_insert_id == 0 (This is the normal case) + In this case we set the set the column for the first row to the value + next_insert_id(get_auto_increment(column))) which is normally + max-used-column-value +1. + + We call get_auto_increment() only for the first row in a multi-row + statement. For the following rows we generate new numbers based on the + last used number. + + - thd->next_insert_id != 0. This happens when we have read a statement + from the binary log or when one has used SET LAST_INSERT_ID=#. + + In this case we will set the column to the value of next_insert_id. + The next row will be given the id + next_insert_id(next_insert_id) + + The idea is that generated auto_increment values are predictable and + independent of the column values in the table. This is needed to be + able to replicate into a table that already has rows with a higher + auto-increment value than the one that is inserted. + + After we have already generated an auto-increment number and the user + inserts a column with a higher value than the last used one, we will + start counting from the inserted value. + + thd->next_insert_id is cleared after it's been used for a statement. */ void handler::update_auto_increment() { - longlong nr; - THD *thd; + ulonglong nr; + THD *thd= table->in_use; + struct system_variables *variables= &thd->variables; DBUG_ENTER("handler::update_auto_increment"); - if (table->next_number_field->val_int() != 0 || + + /* + We must save the previous value to be able to restore it if the + row was not inserted + */ + thd->prev_insert_id= thd->next_insert_id; + + if ((nr= table->next_number_field->val_int()) != 0 || table->auto_increment_field_not_null && - current_thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) + thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) { + /* Clear flag for next row */ table->auto_increment_field_not_null= FALSE; + /* Mark that we didn't generate a new value **/ auto_increment_column_changed=0; + + /* Update next_insert_id if we have already generated a value */ + if (thd->clear_next_insert_id && nr >= thd->next_insert_id) + { + if (variables->auto_increment_increment != 1) + nr= next_insert_id(nr, variables); + else + nr++; + thd->next_insert_id= nr; + DBUG_PRINT("info",("next_insert_id: %lu", (ulong) nr)); + } DBUG_VOID_RETURN; } table->auto_increment_field_not_null= FALSE; - thd=current_thd; - if ((nr=thd->next_insert_id)) - thd->next_insert_id=0; // Clear after use - else - nr=get_auto_increment(); - if (!table->next_number_field->store(nr)) + if (!(nr= thd->next_insert_id)) + { + nr= get_auto_increment(); + if (variables->auto_increment_increment != 1) + nr= next_insert_id(nr-1, variables); + /* + Update next row based on the found value. This way we don't have to + call the handler for every generated auto-increment value on a + multi-row statement + */ + thd->next_insert_id= nr; + } + + DBUG_PRINT("info",("auto_increment: %lu", (ulong) nr)); + + /* Mark that we should clear next_insert_id before next stmt */ + thd->clear_next_insert_id= 1; + + if (!table->next_number_field->store((longlong) nr)) thd->insert_id((ulonglong) nr); else thd->insert_id(table->next_number_field->val_int()); + + /* + We can't set next_insert_id if the auto-increment key is not the + first key part, as there is no guarantee that the first parts will be in + sequence + */ + if (!table->next_number_key_offset) + { + /* + Set next insert id to point to next auto-increment value to be able to + handle multi-row statements + This works even if auto_increment_increment > 1 + */ + thd->next_insert_id= next_insert_id(nr, variables); + } + else + thd->next_insert_id= 0; + + /* Mark that we generated a new value */ auto_increment_column_changed=1; DBUG_VOID_RETURN; } +/* + restore_auto_increment + + In case of error on write, we restore the last used next_insert_id value + because the previous value was not used. +*/ + +void handler::restore_auto_increment() +{ + THD *thd= table->in_use; + if (thd->next_insert_id) + thd->next_insert_id= thd->prev_insert_id; +} + -longlong handler::get_auto_increment() +ulonglong handler::get_auto_increment() { - longlong nr; + ulonglong nr; int error; (void) extra(HA_EXTRA_KEYREAD); @@ -1018,7 +1140,8 @@ longlong handler::get_auto_increment() else { byte key[MAX_KEY_LENGTH]; - key_copy(key,table,table->next_number_index, + key_copy(key, table->record[0], + table->key_info + table->next_number_index, table->next_number_key_offset); error=index_read(table->record[1], key, table->next_number_key_offset, HA_READ_PREFIX_LAST); @@ -1027,8 +1150,8 @@ longlong handler::get_auto_increment() if (error) nr=1; else - nr=(longlong) table->next_number_field-> - val_int_offset(table->rec_buff_length)+1; + nr=((ulonglong) table->next_number_field-> + val_int_offset(table->rec_buff_length)+1); index_end(); (void) extra(HA_EXTRA_NO_KEYREAD); return nr; @@ -1271,7 +1394,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, char name_buff[FN_REFLEN]; DBUG_ENTER("ha_create_table"); - if (openfrm(name,"",0,(uint) READ_ALL, 0, &table)) + if (openfrm(current_thd, name,"",0,(uint) READ_ALL, 0, &table)) DBUG_RETURN(1); if (update_create_info) { @@ -1336,7 +1459,7 @@ int ha_create_table_from_engine(THD* thd, if ((error = writefrm(path, frmblob, frmlen))) goto err_end; - if (openfrm(path,"",0,(uint) READ_ALL, 0, &table)) + if (openfrm(thd, path,"",0,(uint) READ_ALL, 0, &table)) DBUG_RETURN(1); update_create_info_from_table(&create_info, &table); diff --git a/sql/lex.h b/sql/lex.h index 325d052de90..db31b3af994 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -65,6 +65,7 @@ static SYMBOL symbols[] = { { "AGAINST", SYM(AGAINST)}, { "AGGREGATE", SYM(AGGREGATE_SYM)}, { "ALL", SYM(ALL)}, + { "ALGORITHM", SYM(ALGORITHM_SYM)}, { "ALTER", SYM(ALTER)}, { "ANALYZE", SYM(ANALYZE_SYM)}, { "AND", SYM(AND_SYM)}, @@ -72,6 +73,7 @@ static SYMBOL symbols[] = { { "AS", SYM(AS)}, { "ASC", SYM(ASC)}, { "ASCII", SYM(ASCII_SYM)}, + { "ASENSITIVE", SYM(ASENSITIVE_SYM)}, { "AUTO_INCREMENT", SYM(AUTO_INC)}, { "AVG", SYM(AVG_SYM)}, { "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH)}, @@ -93,7 +95,9 @@ static SYMBOL symbols[] = { { "BY", SYM(BY)}, { "BYTE", SYM(BYTE_SYM)}, { "CACHE", SYM(CACHE_SYM)}, + { "CALL", SYM(CALL_SYM)}, { "CASCADE", SYM(CASCADE)}, + { "CASCADED", SYM(CASCADED)}, { "CASE", SYM(CASE_SYM)}, { "CHANGE", SYM(CHANGE)}, { "CHANGED", SYM(CHANGED)}, @@ -114,8 +118,12 @@ static SYMBOL symbols[] = { { "COMMITTED", SYM(COMMITTED_SYM)}, { "COMPRESSED", SYM(COMPRESSED_SYM)}, { "CONCURRENT", SYM(CONCURRENT)}, + { "CONDITION", SYM(CONDITION_SYM)}, + { "CONNECTION", SYM(CONNECTION_SYM)}, { "CONSISTENT", SYM(CONSISTENT_SYM)}, { "CONSTRAINT", SYM(CONSTRAINT)}, + { "CONTAINS", SYM(CONTAINS_SYM)}, + { "CONTINUE", SYM(CONTINUE_SYM)}, { "CONVERT", SYM(CONVERT_SYM)}, { "CREATE", SYM(CREATE)}, { "CROSS", SYM(CROSS)}, @@ -124,6 +132,7 @@ static SYMBOL symbols[] = { { "CURRENT_TIME", SYM(CURTIME)}, { "CURRENT_TIMESTAMP", SYM(NOW_SYM)}, { "CURRENT_USER", SYM(CURRENT_USER)}, + { "CURSOR", SYM(CURSOR_SYM)}, { "DATA", SYM(DATA_SYM)}, { "DATABASE", SYM(DATABASE)}, { "DATABASES", SYM(DATABASES)}, @@ -137,13 +146,16 @@ static SYMBOL symbols[] = { { "DEALLOCATE", SYM(DEALLOCATE_SYM)}, { "DEC", SYM(DECIMAL_SYM)}, { "DECIMAL", SYM(DECIMAL_SYM)}, + { "DECLARE", SYM(DECLARE_SYM)}, { "DEFAULT", SYM(DEFAULT)}, + { "DEFINER", SYM(DEFINER_SYM)}, { "DELAYED", SYM(DELAYED_SYM)}, { "DELAY_KEY_WRITE", SYM(DELAY_KEY_WRITE_SYM)}, { "DELETE", SYM(DELETE_SYM)}, { "DESC", SYM(DESC)}, { "DESCRIBE", SYM(DESCRIBE)}, { "DES_KEY_FILE", SYM(DES_KEY_FILE)}, + { "DETERMINISTIC", SYM(DETERMINISTIC_SYM)}, { "DIRECTORY", SYM(DIRECTORY_SYM)}, { "DISABLE", SYM(DISABLE_SYM)}, { "DISCARD", SYM(DISCARD)}, @@ -157,7 +169,9 @@ static SYMBOL symbols[] = { { "DUMPFILE", SYM(DUMPFILE)}, { "DUPLICATE", SYM(DUPLICATE_SYM)}, { "DYNAMIC", SYM(DYNAMIC_SYM)}, + { "EACH", SYM(EACH_SYM)}, { "ELSE", SYM(ELSE)}, + { "ELSEIF", SYM(ELSEIF_SYM)}, { "ENABLE", SYM(ENABLE_SYM)}, { "ENCLOSED", SYM(ENCLOSED)}, { "END", SYM(END)}, @@ -170,11 +184,13 @@ static SYMBOL symbols[] = { { "EVENTS", SYM(EVENTS_SYM)}, { "EXECUTE", SYM(EXECUTE_SYM)}, { "EXISTS", SYM(EXISTS)}, + { "EXIT", SYM(EXIT_SYM)}, { "EXPANSION", SYM(EXPANSION_SYM)}, { "EXPLAIN", SYM(DESCRIBE)}, { "EXTENDED", SYM(EXTENDED_SYM)}, { "FALSE", SYM(FALSE_SYM)}, { "FAST", SYM(FAST_SYM)}, + { "FETCH", SYM(FETCH_SYM)}, { "FIELDS", SYM(COLUMNS)}, { "FILE", SYM(FILE_SYM)}, { "FIRST", SYM(FIRST_SYM)}, @@ -186,14 +202,17 @@ static SYMBOL symbols[] = { { "FOR", SYM(FOR_SYM)}, { "FORCE", SYM(FORCE_SYM)}, { "FOREIGN", SYM(FOREIGN)}, + { "FOUND", SYM(FOUND_SYM)}, + { "FRAC_SECOND", SYM(FRAC_SECOND_SYM)}, { "FROM", SYM(FROM)}, { "FULL", SYM(FULL)}, { "FULLTEXT", SYM(FULLTEXT_SYM)}, - { "FUNCTION", SYM(UDF_SYM)}, + { "FUNCTION", SYM(FUNCTION_SYM)}, { "GEOMETRY", SYM(GEOMETRY_SYM)}, { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)}, { "GET_FORMAT", SYM(GET_FORMAT)}, { "GLOBAL", SYM(GLOBAL_SYM)}, + { "GOTO", SYM(GOTO_SYM)}, { "GRANT", SYM(GRANT)}, { "GRANTS", SYM(GRANTS)}, { "GROUP", SYM(GROUP)}, @@ -218,6 +237,8 @@ static SYMBOL symbols[] = { { "INNER", SYM(INNER_SYM)}, { "INNOBASE", SYM(INNOBASE_SYM)}, { "INNODB", SYM(INNOBASE_SYM)}, + { "INOUT", SYM(INOUT_SYM)}, + { "INSENSITIVE", SYM(INSENSITIVE_SYM)}, { "INSERT", SYM(INSERT)}, { "INSERT_METHOD", SYM(INSERT_METHOD)}, { "INT", SYM(INT_SYM)}, @@ -233,12 +254,17 @@ static SYMBOL symbols[] = { { "IS", SYM(IS)}, { "ISOLATION", SYM(ISOLATION)}, { "ISSUER", SYM(ISSUER_SYM)}, + { "ITERATE", SYM(ITERATE_SYM)}, + { "INVOKER", SYM(INVOKER_SYM)}, { "JOIN", SYM(JOIN_SYM)}, { "KEY", SYM(KEY_SYM)}, { "KEYS", SYM(KEYS)}, { "KILL", SYM(KILL_SYM)}, + { "LABEL", SYM(LABEL_SYM)}, + { "LANGUAGE", SYM(LANGUAGE_SYM)}, { "LAST", SYM(LAST_SYM)}, { "LEADING", SYM(LEADING)}, + { "LEAVE", SYM(LEAVE_SYM)}, { "LEAVES", SYM(LEAVES)}, { "LEFT", SYM(LEFT)}, { "LEVEL", SYM(LEVEL_SYM)}, @@ -256,6 +282,7 @@ static SYMBOL symbols[] = { { "LONG", SYM(LONG_SYM)}, { "LONGBLOB", SYM(LONGBLOB)}, { "LONGTEXT", SYM(LONGTEXT)}, + { "LOOP", SYM(LOOP_SYM)}, { "LOW_PRIORITY", SYM(LOW_PRIORITY)}, { "MASTER", SYM(MASTER_SYM)}, { "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM)}, @@ -281,6 +308,7 @@ static SYMBOL symbols[] = { { "MEDIUMBLOB", SYM(MEDIUMBLOB)}, { "MEDIUMINT", SYM(MEDIUMINT)}, { "MEDIUMTEXT", SYM(MEDIUMTEXT)}, + { "MERGE", SYM(MERGE_SYM)}, { "MICROSECOND", SYM(MICROSECOND_SYM)}, { "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */ { "MINUTE", SYM(MINUTE_SYM)}, @@ -289,11 +317,13 @@ static SYMBOL symbols[] = { { "MIN_ROWS", SYM(MIN_ROWS)}, { "MOD", SYM(MOD_SYM)}, { "MODE", SYM(MODE_SYM)}, + { "MODIFIES", SYM(MODIFIES_SYM)}, { "MODIFY", SYM(MODIFY_SYM)}, { "MONTH", SYM(MONTH_SYM)}, { "MULTILINESTRING", SYM(MULTILINESTRING)}, { "MULTIPOINT", SYM(MULTIPOINT)}, { "MULTIPOLYGON", SYM(MULTIPOLYGON)}, + { "NAME", SYM(NAME_SYM)}, { "NAMES", SYM(NAMES_SYM)}, { "NATIONAL", SYM(NATIONAL_SYM)}, { "NATURAL", SYM(NATURAL)}, @@ -319,6 +349,7 @@ static SYMBOL symbols[] = { { "OPTIONALLY", SYM(OPTIONALLY)}, { "OR", SYM(OR_SYM)}, { "ORDER", SYM(ORDER_SYM)}, + { "OUT", SYM(OUT_SYM)}, { "OUTER", SYM(OUTER)}, { "OUTFILE", SYM(OUTFILE)}, { "PACK_KEYS", SYM(PACK_KEYS_SYM)}, @@ -335,6 +366,7 @@ static SYMBOL symbols[] = { { "PROCESS" , SYM(PROCESS)}, { "PROCESSLIST", SYM(PROCESSLIST_SYM)}, { "PURGE", SYM(PURGE)}, + { "QUARTER", SYM(QUARTER_SYM)}, { "QUERY", SYM(QUERY_SYM)}, { "QUICK", SYM(QUICK)}, { "RAID0", SYM(RAID_0_SYM)}, @@ -342,6 +374,7 @@ static SYMBOL symbols[] = { { "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE)}, { "RAID_TYPE", SYM(RAID_TYPE)}, { "READ", SYM(READ_SYM)}, + { "READS", SYM(READS_SYM)}, { "REAL", SYM(REAL)}, { "REFERENCES", SYM(REFERENCES)}, { "REGEXP", SYM(REGEXP)}, @@ -354,11 +387,13 @@ static SYMBOL symbols[] = { { "REPEATABLE", SYM(REPEATABLE_SYM)}, { "REPLACE", SYM(REPLACE)}, { "REPLICATION", SYM(REPLICATION)}, + { "REPEAT", SYM(REPEAT_SYM)}, { "REQUIRE", SYM(REQUIRE_SYM)}, { "RESET", SYM(RESET_SYM)}, { "RESTORE", SYM(RESTORE_SYM)}, { "RESTRICT", SYM(RESTRICT)}, - { "RETURNS", SYM(UDF_RETURNS_SYM)}, + { "RETURN", SYM(RETURN_SYM)}, + { "RETURNS", SYM(RETURNS_SYM)}, { "REVOKE", SYM(REVOKE)}, { "RIGHT", SYM(RIGHT)}, { "RLIKE", SYM(REGEXP)}, /* Like in mSQL2 */ @@ -369,9 +404,13 @@ static SYMBOL symbols[] = { { "ROW_FORMAT", SYM(ROW_FORMAT_SYM)}, { "RTREE", SYM(RTREE_SYM)}, { "SAVEPOINT", SYM(SAVEPOINT_SYM)}, + { "SCHEMA", SYM(DATABASE)}, + { "SCHEMAS", SYM(DATABASES)}, { "SECOND", SYM(SECOND_SYM)}, { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM)}, + { "SECURITY", SYM(SECURITY_SYM)}, { "SELECT", SYM(SELECT_SYM)}, + { "SENSITIVE", SYM(SENSITIVE_SYM)}, { "SEPARATOR", SYM(SEPARATOR_SYM)}, { "SERIAL", SYM(SERIAL_SYM)}, { "SERIALIZABLE", SYM(SERIALIZABLE_SYM)}, @@ -389,6 +428,11 @@ static SYMBOL symbols[] = { { "SONAME", SYM(UDF_SONAME_SYM)}, { "SOUNDS", SYM(SOUNDS_SYM)}, { "SPATIAL", SYM(SPATIAL_SYM)}, + { "SPECIFIC", SYM(SPECIFIC_SYM)}, + { "SQL", SYM(SQL_SYM)}, + { "SQLEXCEPTION", SYM(SQLEXCEPTION_SYM)}, + { "SQLSTATE", SYM(SQLSTATE_SYM)}, + { "SQLWARNING", SYM(SQLWARNING_SYM)}, { "SQL_BIG_RESULT", SYM(SQL_BIG_RESULT)}, { "SQL_BUFFER_RESULT", SYM(SQL_BUFFER_RESULT)}, { "SQL_CACHE", SYM(SQL_CACHE_SYM)}, @@ -396,6 +440,15 @@ static SYMBOL symbols[] = { { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM)}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT)}, { "SQL_THREAD", SYM(SQL_THREAD)}, + { "SQL_TSI_FRAC_SECOND", SYM(FRAC_SECOND_SYM)}, + { "SQL_TSI_SECOND", SYM(SECOND_SYM)}, + { "SQL_TSI_MINUTE", SYM(MINUTE_SYM)}, + { "SQL_TSI_HOUR", SYM(HOUR_SYM)}, + { "SQL_TSI_DAY", SYM(DAY_SYM)}, + { "SQL_TSI_WEEK", SYM(WEEK_SYM)}, + { "SQL_TSI_MONTH", SYM(MONTH_SYM)}, + { "SQL_TSI_QUARTER", SYM(QUARTER_SYM)}, + { "SQL_TSI_YEAR", SYM(YEAR_SYM)}, { "SSL", SYM(SSL_SYM)}, { "START", SYM(START_SYM)}, { "STARTING", SYM(STARTING)}, @@ -411,22 +464,28 @@ static SYMBOL symbols[] = { { "TABLES", SYM(TABLES)}, { "TABLESPACE", SYM(TABLESPACE)}, { "TEMPORARY", SYM(TEMPORARY)}, + { "TEMPTABLE", SYM(TEMPTABLE_SYM)}, { "TERMINATED", SYM(TERMINATED)}, { "TEXT", SYM(TEXT_SYM)}, { "THEN", SYM(THEN_SYM)}, { "TIME", SYM(TIME_SYM)}, { "TIMESTAMP", SYM(TIMESTAMP)}, + { "TIMESTAMPADD", SYM(TIMESTAMP_ADD)}, + { "TIMESTAMPDIFF", SYM(TIMESTAMP_DIFF)}, { "TINYBLOB", SYM(TINYBLOB)}, { "TINYINT", SYM(TINYINT)}, { "TINYTEXT", SYM(TINYTEXT)}, { "TO", SYM(TO_SYM)}, { "TRAILING", SYM(TRAILING)}, { "TRANSACTION", SYM(TRANSACTION_SYM)}, + { "TRIGGER", SYM(TRIGGER_SYM)}, { "TRUE", SYM(TRUE_SYM)}, { "TRUNCATE", SYM(TRUNCATE_SYM)}, { "TYPE", SYM(TYPE_SYM)}, { "TYPES", SYM(TYPES_SYM)}, { "UNCOMMITTED", SYM(UNCOMMITTED_SYM)}, + { "UNDEFINED", SYM(UNDEFINED_SYM)}, + { "UNDO", SYM(UNDO_SYM)}, { "UNICODE", SYM(UNICODE_SYM)}, { "UNION", SYM(UNION_SYM)}, { "UNIQUE", SYM(UNIQUE_SYM)}, @@ -451,8 +510,11 @@ static SYMBOL symbols[] = { { "VARIABLES", SYM(VARIABLES)}, { "VARYING", SYM(VARYING)}, { "WARNINGS", SYM(WARNINGS)}, + { "WEEK", SYM(WEEK_SYM)}, { "WHEN", SYM(WHEN_SYM)}, { "WHERE", SYM(WHERE)}, + { "WHILE", SYM(WHILE_SYM)}, + { "VIEW", SYM(VIEW_SYM)}, { "WITH", SYM(WITH)}, { "WORK", SYM(WORK_SYM)}, { "WRITE", SYM(WRITE_SYM)}, @@ -499,7 +561,6 @@ static SYMBOL sql_functions[] = { { "CONCAT", SYM(CONCAT)}, { "CONCAT_WS", SYM(CONCAT_WS)}, { "CONNECTION_ID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, - { "CONTAINS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)}, { "CONV", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, { "CONVERT_TZ", SYM(CONVERT_TZ_SYM)}, { "COUNT", SYM(COUNT_SYM)}, @@ -636,14 +697,13 @@ static SYMBOL sql_functions[] = { { "POSITION", SYM(POSITION_SYM)}, { "POW", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, { "POWER", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, - { "QUARTER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quarter)}, { "QUOTE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)}, { "RADIANS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)}, { "RAND", SYM(RAND)}, { "RELEASE_LOCK", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)}, - { "REPEAT", F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_repeat)}, { "REVERSE", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)}, { "ROUND", SYM(ROUND)}, + { "ROW_COUNT", SYM(ROW_COUNT_SYM)}, { "RPAD", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)}, { "RTRIM", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)}, { "SEC_TO_TIME", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sec_to_time)}, @@ -686,7 +746,6 @@ static SYMBOL sql_functions[] = { { "UUID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_uuid)}, { "VARIANCE", SYM(VARIANCE_SYM)}, { "VERSION", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)}, - { "WEEK", SYM(WEEK_SYM)}, { "WEEKDAY", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)}, { "WEEKOFYEAR", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekofyear)}, { "WITHIN", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_within)}, diff --git a/sql/log.cc b/sql/log.cc index bcd99326501..86b76ed883e 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -35,7 +35,7 @@ #include "message.h" #endif -MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; +MYSQL_LOG mysql_log, mysql_slow_log, mysql_bin_log; ulong sync_binlog_counter= 0; static bool test_if_number(const char *str, @@ -129,7 +129,8 @@ static int find_uniq_filename(char *name) MYSQL_LOG::MYSQL_LOG() :bytes_written(0), last_time(0), query_start(0), name(0), file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0), - need_start_event(1) + need_start_event(1), description_event_for_exec(0), + description_event_for_queue(0) { /* We don't want to initialize LOCK_Log here as such initialization depends on @@ -157,6 +158,8 @@ void MYSQL_LOG::cleanup() { inited= 0; close(LOG_CLOSE_INDEX); + delete description_event_for_queue; + delete description_event_for_exec; (void) pthread_mutex_destroy(&LOCK_log); (void) pthread_mutex_destroy(&LOCK_index); (void) pthread_cond_destroy(&update_cond); @@ -226,7 +229,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, const char *new_name, const char *index_file_name_arg, enum cache_type io_cache_type_arg, bool no_auto_events_arg, - ulong max_size_arg) + ulong max_size_arg, + bool null_created_arg) { char buff[512]; File file= -1, index_file_nr= -1; @@ -324,8 +328,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE)) goto err; - bytes_written += BIN_LOG_HEADER_SIZE; - write_file_name_to_index_file=1; + bytes_written+= BIN_LOG_HEADER_SIZE; + write_file_name_to_index_file= 1; } if (!my_b_inited(&index_file)) @@ -355,10 +359,50 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, } if (need_start_event && !no_auto_events) { - need_start_event=0; - Start_log_event s; - s.set_log_pos(this); - s.write(&log_file); + /* + In 4.x we set need_start_event=0 here, but in 5.0 we want a Start event + even if this is not the very first binlog. + */ + Format_description_log_event s(BINLOG_VERSION); + if (!s.is_valid()) + goto err; + if (null_created_arg) + s.created= 0; + if (s.write(&log_file)) + goto err; + bytes_written+= s.data_written; + } + if (description_event_for_queue && + description_event_for_queue->binlog_version>=4) + { + /* + This is a relay log written to by the I/O slave thread. + Write the event so that others can later know the format of this relay + log. + Note that this event is very close to the original event from the + master (it has binlog version of the master, event types of the + master), so this is suitable to parse the next relay log's event. It + has been produced by + Format_description_log_event::Format_description_log_event(char* + buf,). + Why don't we want to write the description_event_for_queue if this + event is for format<4 (3.23 or 4.x): this is because in that case, the + description_event_for_queue describes the data received from the + master, but not the data written to the relay log (*conversion*), + which is in format 4 (slave's). + */ + /* + Set 'created' to 0, so that in next relay logs this event does not + trigger cleaning actions on the slave in + Format_description_log_event::exec_event(). + */ + description_event_for_queue->created= 0; + /* Don't set log_pos in event header */ + description_event_for_queue->artificial_event=1; + + if (description_event_for_queue->write(&log_file)) + goto err; + bytes_written+= description_event_for_queue->data_written; } if (flush_io_cache(&log_file) || my_sync(log_file.file, MYF(MY_WME))) @@ -654,7 +698,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) if (!thd->slave_thread) need_start_event=1; open(save_name, save_log_type, 0, index_file_name, - io_cache_type, no_auto_events, max_size); + io_cache_type, no_auto_events, max_size, 0); my_free((gptr) save_name, MYF(0)); err: @@ -836,22 +880,18 @@ int MYSQL_LOG::purge_logs(const char *to_log, while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) && !log_in_use(log_info.log_file_name)) { - ulong tmp; - LINT_INIT(tmp); + ulong file_size= 0; if (decrease_log_space) //stat the file we want to delete { MY_STAT s; + + /* + If we could not stat, we can't know the amount + of space that deletion will free. In most cases, + deletion won't work either, so it's not a problem. + */ if (my_stat(log_info.log_file_name,&s,MYF(0))) - tmp= s.st_size; - else - { - /* - If we could not stat, we can't know the amount - of space that deletion will free. In most cases, - deletion won't work either, so it's not a problem. - */ - tmp= 0; - } + file_size= s.st_size; } /* It's not fatal if we can't delete a log file ; @@ -859,7 +899,7 @@ int MYSQL_LOG::purge_logs(const char *to_log, */ DBUG_PRINT("info",("purging %s",log_info.log_file_name)); if (!my_delete(log_info.log_file_name, MYF(0)) && decrease_log_space) - *decrease_log_space-= tmp; + *decrease_log_space-= file_size; if (find_next_log(&log_info, 0) || exit_loop) break; } @@ -1024,9 +1064,8 @@ void MYSQL_LOG::new_file(bool need_lock) */ THD *thd = current_thd; /* may be 0 if we are reacting to SIGHUP */ Rotate_log_event r(thd,new_name+dirname_length(new_name)); - r.set_log_pos(this); r.write(&log_file); - bytes_written += r.get_event_len(); + bytes_written += r.data_written; } /* Update needs to be signalled even if there is no rotate event @@ -1044,8 +1083,17 @@ void MYSQL_LOG::new_file(bool need_lock) Note that at this point, log_type != LOG_CLOSED (important for is_open()). */ + /* + new_file() is only used for rotation (in FLUSH LOGS or because size > + max_binlog_size or max_relay_log_size). + If this is a binary log, the Format_description_log_event at the beginning of + the new file should have created=0 (to distinguish with the + Format_description_log_event written at server startup, which should + trigger temp tables deletion on slaves. + */ + open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type, - no_auto_events, max_size); + no_auto_events, max_size, 1); if (this == &mysql_bin_log) report_pos_in_innodb(); my_free(old_name,MYF(0)); @@ -1076,7 +1124,7 @@ bool MYSQL_LOG::append(Log_event* ev) error=1; goto err; } - bytes_written += ev->get_event_len(); + bytes_written+= ev->data_written; DBUG_PRINT("info",("max_size: %lu",max_size)); if ((uint) my_b_append_tell(&log_file) > max_size) { @@ -1129,7 +1177,7 @@ err: /* Write to normal (not rotable) log - This is the format for the 'normal', 'slow' and 'update' logs. + This is the format for the 'normal' log. */ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, @@ -1220,11 +1268,15 @@ bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, inline bool sync_binlog(IO_CACHE *cache) { - return (sync_binlog_period && - (sync_binlog_period == ++sync_binlog_counter) && - (sync_binlog_counter= 0, my_sync(cache->file, MYF(MY_WME)))); + if (sync_binlog_period == ++sync_binlog_counter && sync_binlog_period) + { + sync_binlog_counter= 0; + return my_sync(cache->file, MYF(MY_WME)); + } + return 0; } + /* Write an event to the binary log */ @@ -1292,7 +1344,7 @@ bool MYSQL_LOG::write(Log_event* event_info) if (thd) { -#if MYSQL_VERSION_ID < 50000 + /* NOTE: CHARSET AND TZ REPL WILL BE REWRITTEN SHORTLY */ /* To make replication of charsets working in 4.1 we are writing values of charset related variables before every statement in the binlog, @@ -1318,7 +1370,6 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", (uint) thd->variables.collation_database->number, (uint) thd->variables.collation_server->number); Query_log_event e(thd, buf, written, 0); - e.set_log_pos(this); if (e.write(file)) goto err; } @@ -1334,31 +1385,26 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", thd->variables.time_zone->get_name()->ptr(), "'", NullS); Query_log_event e(thd, buf, buf_end - buf, 0); - e.set_log_pos(this); if (e.write(file)) goto err; } -#endif if (thd->last_insert_id_used) { Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT, thd->current_insert_id); - e.set_log_pos(this); if (e.write(file)) goto err; } if (thd->insert_id_used) { Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id); - e.set_log_pos(this); if (e.write(file)) goto err; } if (thd->rand_used) { Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2); - e.set_log_pos(this); if (e.write(file)) goto err; } @@ -1374,7 +1420,6 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", user_var_event->length, user_var_event->type, user_var_event->charset_number); - e.set_log_pos(this); if (e.write(file)) goto err; } @@ -1386,48 +1431,17 @@ COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u", p= strmov(strmov(buf, "SET CHARACTER SET "), thd->variables.convert_set->name); Query_log_event e(thd, buf, (ulong) (p - buf), 0); - e.set_log_pos(this); if (e.write(file)) goto err; } #endif - - /* - If the user has set FOREIGN_KEY_CHECKS=0 we wrap every SQL - command in the binlog inside: - SET FOREIGN_KEY_CHECKS=0; - ; - SET FOREIGN_KEY_CHECKS=1; - */ - - if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) - { - Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=0", 24, 0); - e.set_log_pos(this); - if (e.write(file)) - goto err; - } } /* Write the SQL command */ - event_info->set_log_pos(this); if (event_info->write(file)) goto err; - /* Write log events to reset the 'run environment' of the SQL command */ - - if (thd) - { - if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) - { - Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0); - e.set_log_pos(this); - if (e.write(file)) - goto err; - } - } - /* Tell for transactional table handlers up to which position in the binlog file we wrote. The table handler can store this info, and @@ -1604,7 +1618,6 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) master's binlog, which would result in wrong positions being shown to the user, MASTER_POS_WAIT undue waiting etc. */ - qinfo.set_log_pos(this); if (qinfo.write(&log_file)) goto err; } @@ -1630,7 +1643,6 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, bool commit_or_rollback) commit_or_rollback ? "COMMIT" : "ROLLBACK", commit_or_rollback ? 6 : 8, TRUE); - qinfo.set_log_pos(this); if (qinfo.write(&log_file) || flush_io_cache(&log_file) || sync_binlog(&log_file)) goto err; @@ -1692,8 +1704,7 @@ err: /* - Write update log in a format suitable for incremental backup - This is also used by the slow query log. + Write to the slow query log. */ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, @@ -1877,8 +1888,8 @@ void MYSQL_LOG::close(uint exiting) (exiting & LOG_CLOSE_STOP_EVENT)) { Stop_log_event s; - s.set_log_pos(this); s.write(&log_file); + bytes_written+= s.data_written; signal_update(); } #endif /* HAVE_REPLICATION */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 091566c5d90..7fba19cb000 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -180,10 +180,12 @@ static void cleanup_load_tmpdir() write_str() */ -static bool write_str(IO_CACHE *file, char *str, byte length) +static bool write_str(IO_CACHE *file, char *str, uint length) { - return (my_b_safe_write(file, &length, 1) || - my_b_safe_write(file, (byte*) str, (int) length)); + byte tmp[1]; + tmp[0]= (byte) length; + return (my_b_safe_write(file, tmp, sizeof(tmp)) || + my_b_safe_write(file, (byte*) str, length)); } @@ -191,17 +193,18 @@ static bool write_str(IO_CACHE *file, char *str, byte length) read_str() */ -static inline int read_str(char * &buf, char *buf_end, char * &str, - uint8 &len) +static inline int read_str(char **buf, char *buf_end, char **str, + uint8 *len) { - if (buf + (uint) (uchar) *buf >= buf_end) + if (*buf + ((uint) (uchar) **buf) >= buf_end) return 1; - len = (uint8) *buf; - str= buf+1; - buf+= (uint) len+1; + *len= (uint8) **buf; + *str= (*buf)+1; + (*buf)+= (uint) *len+1; return 0; } + /* Transforms a string into "" or its expression in 0x... form. */ @@ -225,9 +228,25 @@ static char *str_to_hex(char *to, char *from, uint len) return p; // pointer to end 0 of 'to' } +/* + Prints a "session_var=value" string. Used by mysqlbinlog to print some SET + commands just before it prints a query. +*/ + +static void print_set_option(FILE* file, uint32 bits_changed, uint32 option, + uint32 flags, const char* name, bool* need_comma) +{ + if (bits_changed & option) + { + if (*need_comma) + fprintf(file,", "); + fprintf(file,"%s=%d", name, (bool)(flags & option)); + *need_comma= 1; + } +} /************************************************************************** - Log_event methods + Log_event methods (= the parent class of all events) **************************************************************************/ /* @@ -237,7 +256,7 @@ static char *str_to_hex(char *to, char *from, uint len) const char* Log_event::get_type_str() { switch(get_type_code()) { - case START_EVENT: return "Start"; + case START_EVENT_V3: return "Start_v3"; case STOP_EVENT: return "Stop"; case QUERY_EVENT: return "Query"; case ROTATE_EVENT: return "Rotate"; @@ -251,6 +270,7 @@ const char* Log_event::get_type_str() case EXEC_LOAD_EVENT: return "Exec_load"; case RAND_EVENT: return "RAND"; case USER_VAR_EVENT: return "User var"; + case FORMAT_DESCRIPTION_EVENT: return "Format_desc"; default: return "Unknown"; /* impossible */ } } @@ -262,8 +282,7 @@ const char* Log_event::get_type_str() #ifndef MYSQL_CLIENT Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) - :log_pos(0), temp_buf(0), exec_time(0), cached_event_len(0), - flags(flags_arg), thd(thd_arg) + :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg) { server_id= thd->server_id; when= thd->start_time; @@ -280,7 +299,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) */ Log_event::Log_event() - :temp_buf(0), exec_time(0), cached_event_len(0), flags(0), cache_stmt(0), + :temp_buf(0), exec_time(0), flags(0), cache_stmt(0), thd(0) { server_id= ::server_id; @@ -294,24 +313,70 @@ Log_event::Log_event() Log_event::Log_event() */ -Log_event::Log_event(const char* buf, bool old_format) - :temp_buf(0), cached_event_len(0), cache_stmt(0) +Log_event::Log_event(const char* buf, + const Format_description_log_event* description_event) + :temp_buf(0), cache_stmt(0) { +#ifndef MYSQL_CLIENT + thd = 0; +#endif when = uint4korr(buf); server_id = uint4korr(buf + SERVER_ID_OFFSET); - if (old_format) + if (description_event->binlog_version==1) { - log_pos=0; - flags=0; + log_pos= 0; + flags= 0; + return; } - else + /* 4.0 or newer */ + log_pos= uint4korr(buf + LOG_POS_OFFSET); + /* + If the log is 4.0 (so here it can only be a 4.0 relay log read by the SQL + thread or a 4.0 master binlog read by the I/O thread), log_pos is the + beginning of the event: we transform it into the end of the event, which is + more useful. + But how do you know that the log is 4.0: you know it if description_event + is version 3 *and* you are not reading a Format_desc (remember that + mysqlbinlog starts by assuming that 5.0 logs are in 4.0 format, until it + finds a Format_desc). + */ + if (description_event->binlog_version==3 && + buf[EVENT_TYPE_OFFSET]group_master_log_pos" (see + inc_group_relay_log_pos()). As it is unreal log_pos, adding the event + len's is nonsense. For example, a fake Rotate event should + not have its log_pos (which is 0) changed or it will modify + Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense value + of (a non-zero offset which does not exist in the master's binlog, so + which will cause problems if the user uses this value in + CHANGE MASTER). + */ + log_pos+= uint4korr(buf + EVENT_LEN_OFFSET); } -#ifndef MYSQL_CLIENT - thd = 0; -#endif + DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos)); + + flags= uint2korr(buf + FLAGS_OFFSET); + if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) || + (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT)) + { + /* + These events always have a header which stops here (i.e. their header is + FROZEN). + */ + /* + Initialization to zero of all other Log_event members as they're not + specified. Currently there are no such members; in the future there will + be an event UID (but Format_description and Rotate don't need this UID, + as they are not propagated through --log-slave-updates (remember the UID + is used to not play a query twice when you have two masters which are + slaves of a 3rd master). Then we are done. + */ + return; + } + /* otherwise, go on with reading the header from buf (nothing now) */ } #ifndef MYSQL_CLIENT @@ -364,10 +429,10 @@ int Log_event::exec_event(struct st_relay_log_info* rli) has already been updated. */ if ((thd->options & OPTION_BEGIN) && opt_using_transactions) - rli->inc_event_relay_log_pos(get_event_len()); + rli->inc_event_relay_log_pos(); else { - rli->inc_group_relay_log_pos(get_event_len(),log_pos); + rli->inc_group_relay_log_pos(log_pos); flush_relay_log_info(rli); /* Note that Rotate_log_event::exec_event() does not call this function, @@ -429,49 +494,95 @@ void Log_event::init_show_field_list(List* field_list) field_list->push_back(new Item_empty_string("Event_type", 20)); field_list->push_back(new Item_return_int("Server_id", 10, MYSQL_TYPE_LONG)); - field_list->push_back(new Item_return_int("Orig_log_pos", 11, + field_list->push_back(new Item_return_int("End_log_pos", 11, MYSQL_TYPE_LONGLONG)); field_list->push_back(new Item_empty_string("Info", 20)); } #endif /* !MYSQL_CLIENT */ + /* Log_event::write() */ -int Log_event::write(IO_CACHE* file) +bool Log_event::write_header(IO_CACHE* file, ulong event_data_length) { - return (write_header(file) || write_data(file)) ? -1 : 0; -} + byte header[LOG_EVENT_HEADER_LEN]; + DBUG_ENTER("Log_event::write_header"); + /* Store number of bytes that will be written by this event */ + data_written= event_data_length + sizeof(header); -/* - Log_event::write_header() -*/ + /* + log_pos != 0 if this is relay-log event. In this case we should not + change the position + */ -int Log_event::write_header(IO_CACHE* file) -{ - char buf[LOG_EVENT_HEADER_LEN]; - char* pos = buf; - int4store(pos, (ulong) when); // timestamp - pos += 4; - *pos++ = get_type_code(); // event type code - int4store(pos, server_id); - pos += 4; - long tmp=get_data_size() + LOG_EVENT_HEADER_LEN; - int4store(pos, tmp); - pos += 4; - int4store(pos, log_pos); - pos += 4; - int2store(pos, flags); - pos += 2; - return (my_b_safe_write(file, (byte*) buf, (uint) (pos - buf))); + if (is_artificial_event()) + { + /* + We should not do any cleanup on slave when reading this. We + mark this by setting log_pos to 0. Start_log_event_v3() will + detect this on reading and set artificial_event=1 for the event. + */ + log_pos= 0; + } + else if (!log_pos) + { + /* + Calculate position of end of event + + Note that with a SEQ_READ_APPEND cache, my_b_tell() does not + work well. So this will give slightly wrong positions for the + Format_desc/Rotate/Stop events which the slave writes to its + relay log. For example, the initial Format_desc will have + end_log_pos=91 instead of 95. Because after writing the first 4 + bytes of the relay log, my_b_tell() still reports 0. Because + my_b_append() does not update the counter which my_b_tell() + later uses (one should probably use my_b_append_tell() to work + around this). To get right positions even when writing to the + relay log, we use the (new) my_b_safe_tell(). + + Note that this raises a question on the correctness of all these + DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos). + + If in a transaction, the log_pos which we calculate below is not + very good (because then my_b_safe_tell() returns start position + of the BEGIN, so it's like the statement was at the BEGIN's + place), but it's not a very serious problem (as the slave, when + it is in a transaction, does not take those end_log_pos into + account (as it calls inc_event_relay_log_pos()). To be fixed + later, so that it looks less strange. But not bug. + */ + + log_pos= my_b_safe_tell(file)+data_written; + } + + /* + Header will be of size LOG_EVENT_HEADER_LEN for all events, except for + FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be + LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header, + because we read them before knowing the format). + */ + + int4store(header, (ulong) when); // timestamp + header[EVENT_TYPE_OFFSET]= get_type_code(); + int4store(header+ SERVER_ID_OFFSET, server_id); + int4store(header+ EVENT_LEN_OFFSET, data_written); + int4store(header+ LOG_POS_OFFSET, log_pos); + int2store(header+ FLAGS_OFFSET, flags); + + DBUG_RETURN(my_b_safe_write(file, header, sizeof(header)) != 0); } /* Log_event::read_log_event() + + This needn't be format-tolerant, because we only read + LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length). + */ #ifndef MYSQL_CLIENT @@ -480,7 +591,7 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet, { ulong data_len; int result=0; - char buf[LOG_EVENT_HEADER_LEN]; + char buf[LOG_EVENT_MINIMAL_HEADER_LEN]; DBUG_ENTER("read_log_event"); if (log_lock) @@ -500,24 +611,25 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet, goto end; } data_len= uint4korr(buf + EVENT_LEN_OFFSET); - if (data_len < LOG_EVENT_HEADER_LEN || + if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN || data_len > current_thd->variables.max_allowed_packet) { DBUG_PRINT("error",("data_len: %ld", data_len)); - result= ((data_len < LOG_EVENT_HEADER_LEN) ? LOG_READ_BOGUS : + result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS : LOG_READ_TOO_LARGE); goto end; } packet->append(buf, sizeof(buf)); - data_len-= LOG_EVENT_HEADER_LEN; + data_len-= LOG_EVENT_MINIMAL_HEADER_LEN; if (data_len) { if (packet->append(file, data_len)) { /* - Here we should never hit EOF in a non-error condition. + Here if we hit EOF it's really an error: as data_len is >=0 + there's supposed to be more bytes available. EOF means we are reading the event partially, which should - never happen. + never happen: either we read badly or the binlog is truncated. */ result= file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO; /* Implicit goto end; */ @@ -545,24 +657,42 @@ end: Log_event::read_log_event() NOTE: - Allocates memory; The caller is responsible for clean-up + Allocates memory; The caller is responsible for clean-up. */ #ifndef MYSQL_CLIENT Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock, - bool old_format) + const Format_description_log_event *description_event) #else -Log_event* Log_event::read_log_event(IO_CACHE* file, bool old_format) +Log_event* Log_event::read_log_event(IO_CACHE* file, + const Format_description_log_event *description_event) #endif { - char head[LOG_EVENT_HEADER_LEN]; - uint header_size= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; + DBUG_ASSERT(description_event); + char head[LOG_EVENT_MINIMAL_HEADER_LEN]; + /* + First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to + check the event for sanity and to know its length; no need to really parse + it. We say "at most" because this could be a 3.23 master, which has header + of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's "minimal" + over the set {MySQL >=4.0}). + */ + uint header_size= min(description_event->common_header_len, + LOG_EVENT_MINIMAL_HEADER_LEN); LOCK_MUTEX; + DBUG_PRINT("info", ("my_b_tell=%lu", my_b_tell(file))); if (my_b_read(file, (byte *) head, header_size)) { + DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \ +failed my_b_read")); UNLOCK_MUTEX; + /* + No error here; it could be that we are at the file's end. However if the + next my_b_read() fails (below), it will be an error as we were able to + read the first bytes. + */ return 0; } @@ -596,7 +726,8 @@ Log_event* Log_event::read_log_event(IO_CACHE* file, bool old_format) error = "read error"; goto err; } - if ((res = read_log_event(buf, data_len, &error, old_format))) + if ((res= read_log_event(buf, data_len, &error, + description_event))) res->register_temp_buf(buf); err: @@ -623,13 +754,18 @@ Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d", /* Log_event::read_log_event() + Binlog format tolerance is in (buf, event_len, description_event) + constructors. */ -Log_event* Log_event::read_log_event(const char* buf, int event_len, - const char **error, bool old_format) +Log_event* Log_event::read_log_event(const char* buf, uint event_len, + const char **error, + const Format_description_log_event *description_event) { - DBUG_ENTER("Log_event::read_log_event"); - + Log_event* ev; + DBUG_ENTER("Log_event::read_log_event(char*,...)"); + DBUG_ASSERT(description_event); + DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version)); if (event_len < EVENT_LEN_OFFSET || (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET)) { @@ -637,74 +773,87 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len, DBUG_RETURN(NULL); // general sanity check - will fail on a partial read } - Log_event* ev = NULL; - switch(buf[EVENT_TYPE_OFFSET]) { case QUERY_EVENT: - ev = new Query_log_event(buf, event_len, old_format); + ev = new Query_log_event(buf, event_len, description_event); break; case LOAD_EVENT: - ev = new Create_file_log_event(buf, event_len, old_format); + ev = new Create_file_log_event(buf, event_len, description_event); break; case NEW_LOAD_EVENT: - ev = new Load_log_event(buf, event_len, old_format); + ev = new Load_log_event(buf, event_len, description_event); break; case ROTATE_EVENT: - ev = new Rotate_log_event(buf, event_len, old_format); + ev = new Rotate_log_event(buf, event_len, description_event); break; #ifdef HAVE_REPLICATION - case SLAVE_EVENT: + case SLAVE_EVENT: /* can never happen (unused event) */ ev = new Slave_log_event(buf, event_len); break; #endif /* HAVE_REPLICATION */ case CREATE_FILE_EVENT: - ev = new Create_file_log_event(buf, event_len, old_format); + ev = new Create_file_log_event(buf, event_len, description_event); break; case APPEND_BLOCK_EVENT: - ev = new Append_block_log_event(buf, event_len); + ev = new Append_block_log_event(buf, event_len, description_event); break; case DELETE_FILE_EVENT: - ev = new Delete_file_log_event(buf, event_len); + ev = new Delete_file_log_event(buf, event_len, description_event); break; case EXEC_LOAD_EVENT: - ev = new Execute_load_log_event(buf, event_len); + ev = new Execute_load_log_event(buf, event_len, description_event); break; - case START_EVENT: - ev = new Start_log_event(buf, old_format); + case START_EVENT_V3: /* this is sent only by MySQL <=4.x */ + ev = new Start_log_event_v3(buf, description_event); break; #ifdef HAVE_REPLICATION case STOP_EVENT: - ev = new Stop_log_event(buf, old_format); + ev = new Stop_log_event(buf, description_event); break; #endif /* HAVE_REPLICATION */ case INTVAR_EVENT: - ev = new Intvar_log_event(buf, old_format); + ev = new Intvar_log_event(buf, description_event); break; case RAND_EVENT: - ev = new Rand_log_event(buf, old_format); + ev = new Rand_log_event(buf, description_event); break; case USER_VAR_EVENT: - ev = new User_var_log_event(buf, old_format); + ev = new User_var_log_event(buf, description_event); + break; + case FORMAT_DESCRIPTION_EVENT: + ev = new Format_description_log_event(buf, event_len, description_event); break; default: + DBUG_PRINT("error",("Unknown evernt code: %d",(int) buf[EVENT_TYPE_OFFSET])); + ev= NULL; break; } + /* + is_valid() are small event-specific sanity tests which are important; for + example there are some my_malloc() in constructors + (e.g. Query_log_event::Query_log_event(char*...)); when these my_malloc() + fail we can't return an error out of the constructor (because constructor + is "void") ; so instead we leave the pointer we wanted to allocate + (e.g. 'query') to 0 and we test it in is_valid(). Same for + Format_description_log_event, member 'post_header_len'. + */ if (!ev || !ev->is_valid()) { + DBUG_PRINT("error",("Found invalid event in binary log")); + delete ev; #ifdef MYSQL_CLIENT - if (!force_opt) + if (!force_opt) /* then mysqlbinlog dies */ { *error= "Found invalid event in binary log"; DBUG_RETURN(0); } - ev= new Unknown_log_event(buf, old_format); + ev= new Unknown_log_event(buf, description_event); #else *error= "Found invalid event in binary log"; DBUG_RETURN(0); #endif } - ev->cached_event_len = event_len; DBUG_RETURN(ev); } @@ -719,7 +868,7 @@ void Log_event::print_header(FILE* file) char llbuff[22]; fputc('#', file); print_timestamp(file); - fprintf(file, " server id %d log_pos %s ", server_id, + fprintf(file, " server id %d end_log_pos %s ", server_id, llstr(log_pos,llbuff)); } @@ -751,19 +900,6 @@ void Log_event::print_timestamp(FILE* file, time_t* ts) #endif /* MYSQL_CLIENT */ -/* - Log_event::set_log_pos() -*/ - -#ifndef MYSQL_CLIENT -void Log_event::set_log_pos(MYSQL_LOG* log) -{ - if (!log_pos) - log_pos = my_b_tell(&log->log_file); -} -#endif /* !MYSQL_CLIENT */ - - /************************************************************************** Query_log_event methods **************************************************************************/ @@ -772,10 +908,15 @@ void Log_event::set_log_pos(MYSQL_LOG* log) /* Query_log_event::pack_info() + This (which is used only for SHOW BINLOG EVENTS) could be updated to + print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is + only an information, it does not produce suitable queries to replay (for + example it does not print LOAD DATA INFILE). */ void Query_log_event::pack_info(Protocol *protocol) { + // TODO: show the catalog ?? char *buf, *pos; if (!(buf= my_malloc(9 + db_len + q_len, MYF(MY_WME)))) return; @@ -799,31 +940,27 @@ void Query_log_event::pack_info(Protocol *protocol) /* Query_log_event::write() -*/ - -int Query_log_event::write(IO_CACHE* file) -{ - return query ? Log_event::write(file) : -1; -} - -/* - Query_log_event::write_data() + NOTES: + In this event we have to modify the header to have the correct + EVENT_LEN_OFFSET as we don't yet know how many status variables we + will print! */ -int Query_log_event::write_data(IO_CACHE* file) +bool Query_log_event::write(IO_CACHE* file) { - char buf[QUERY_HEADER_LEN]; + uchar buf[QUERY_HEADER_LEN+1+4+1+8+1+1+FN_REFLEN+5], *start, *start_of_status; + ulong event_length; if (!query) - return -1; - + return 1; // Something wrong with event + /* We want to store the thread id: (- as an information for the user when he reads the binlog) - if the query uses temporary table: for the slave SQL thread to know to which master connection the temp table belongs. - Now imagine we (write_data()) are called by the slave SQL thread (we are + Now imagine we (write()) are called by the slave SQL thread (we are logging a query executed by this thread; the slave runs with --log-slave-updates). Then this query will be logged with thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of @@ -860,9 +997,77 @@ int Query_log_event::write_data(IO_CACHE* file) buf[Q_DB_LEN_OFFSET] = (char) db_len; int2store(buf + Q_ERR_CODE_OFFSET, error_code); - return (my_b_safe_write(file, (byte*) buf, QUERY_HEADER_LEN) || - my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) || - my_b_safe_write(file, (byte*) query, q_len)) ? -1 : 0; + /* + You MUST always write status vars in increasing order of code. This + guarantees that a slightly older slave will be able to parse those he + knows. + */ + start_of_status= start= buf+QUERY_HEADER_LEN; + if (flags2_inited) + { + *(start++)= Q_FLAGS2_CODE; + int4store(start, flags2); + start+= 4; + } + if (sql_mode_inited) + { + *(start++)= Q_SQL_MODE_CODE; + int8store(start, sql_mode); + start+= 8; + } + if (catalog_len >= 0) // i.e. "catalog inited" (false for 4.0 events) + { + *(start++)= Q_CATALOG_CODE; + *(start++)= (uchar) catalog_len; + bmove(start, catalog, catalog_len); + start+= catalog_len; + /* + We write a \0 at the end. As we also have written the length, it's + apparently useless; but in fact it enables us to just do + catalog= a_pointer_to_the_buffer_of_the_read_event + later in the slave SQL thread. + If we didn't have the \0, we would need to memdup to build the catalog in + the slave SQL thread. + And still the interest of having the length too is that in the slave SQL + thread we immediately know at which position the catalog ends (no need to + search for '\0'. In other words: length saves search, \0 saves mem alloc, + at the cost of 1 redundant byte on the disk. + Note that this is only a fix until we change 'catalog' to LEX_STRING + (then we won't need the \0). + */ + *(start++)= '\0'; + } + if (auto_increment_increment != 1) + { + *start++= Q_AUTO_INCREMENT; + int2store(start, auto_increment_increment); + int2store(start+2, auto_increment_offset); + start+= 4; + } + /* + Here there could be code like + if (command-line-option-which-says-"log_this_variable") + { + *(start++)= Q_THIS_VARIABLE_CODE; + int4store(start, this_variable); + start+= 4; + } + */ + + /* Store length of status variables */ + status_vars_len= (uint) (start-start_of_status); + int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len); + + /* + Calculate length of whole event + The "1" below is the \0 in the db's length + */ + event_length= (uint) (start-buf) + db_len + 1 + q_len; + + return (write_header(file, event_length) || + my_b_safe_write(file, (byte*) buf, (uint) (start-buf)) || + my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) || + my_b_safe_write(file, (byte*) query, q_len)) ? 1 : 0; } @@ -875,60 +1080,162 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, bool using_trans) :Log_event(thd_arg, !thd_arg->tmp_table_used ? 0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans), - data_buf(0), query(query_arg), + data_buf(0), query(query_arg), catalog(thd_arg->catalog), db(thd_arg->db), q_len((uint32) query_length), - error_code(thd_arg->killed ? + error_code((thd_arg->killed != THD::NOT_KILLED) ? ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? - 0 : ER_SERVER_SHUTDOWN) : thd_arg->net.last_errno), + 0 : thd->killed_errno()) : thd_arg->net.last_errno), thread_id(thd_arg->thread_id), /* save the original thread id; we already know the server id */ - slave_proxy_id(thd_arg->variables.pseudo_thread_id) + slave_proxy_id(thd_arg->variables.pseudo_thread_id), + flags2_inited(1), sql_mode_inited(1), flags2(0), + sql_mode(thd_arg->variables.sql_mode), + auto_increment_increment(thd_arg->variables.auto_increment_increment), + auto_increment_offset(thd_arg->variables.auto_increment_offset) { time_t end_time; time(&end_time); exec_time = (ulong) (end_time - thd->start_time); + catalog_len = (catalog) ? (uint32) strlen(catalog) : 0; + status_vars_len= 1+4+1+8+1+1+catalog_len+1; db_len = (db) ? (uint32) strlen(db) : 0; + /* + If we don't use flags2 for anything else than options contained in + thd->options, it would be more efficient to flags2=thd_arg->options + (OPTIONS_WRITTEN_TO_BINLOG would be used only at reading time). + But it's likely that we don't want to use 32 bits for 3 bits; in the future + we will probably want to reclaim the 29 bits. So we need the &. + */ + flags2= thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG; + + DBUG_PRINT("info",("Query_log_event has flags2=%lu sql_mode=%lu",flags2,sql_mode)); } #endif /* MYSQL_CLIENT */ /* Query_log_event::Query_log_event() + This is used by the SQL slave thread to prepare the event before execution. */ -Query_log_event::Query_log_event(const char* buf, int event_len, - bool old_format) - :Log_event(buf, old_format),data_buf(0), query(NULL), db(NULL) +Query_log_event::Query_log_event(const char* buf, uint event_len, + const Format_description_log_event *description_event) + :Log_event(buf, description_event), data_buf(0), query(NullS), catalog(NullS), + db(NullS), catalog_len(0), status_vars_len(0), + flags2_inited(0), sql_mode_inited(0) { ulong data_len; - if (old_format) + uint32 tmp; + uint8 common_header_len, post_header_len; + const char *start, *end; + DBUG_ENTER("Query_log_event::Query_log_event(char*,...)"); + + common_header_len= description_event->common_header_len; + post_header_len= description_event->post_header_len[QUERY_EVENT-1]; + DBUG_PRINT("info",("event_len=%ld, common_header_len=%d, post_header_len=%d", + event_len, common_header_len, post_header_len)); + + /* + We test if the event's length is sensible, and if so we compute data_len. + We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant. + We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0. + */ + if (event_len < (uint)(common_header_len + post_header_len)) + DBUG_VOID_RETURN; + data_len = event_len - (common_header_len + post_header_len); + buf+= common_header_len; + + slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET); + exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET); + db_len = (uint)buf[Q_DB_LEN_OFFSET]; + error_code = uint2korr(buf + Q_ERR_CODE_OFFSET); + /* If auto_increment is not set by query_event, they should not be used */ + auto_increment_increment= auto_increment_offset= 1; + + /* + 5.0 format starts here. + Depending on the format, we may or not have affected/warnings etc + The remnent post-header to be parsed has length: + */ + tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN; + if (tmp) { - if ((uint)event_len < OLD_HEADER_LEN + QUERY_HEADER_LEN) - return; - data_len = event_len - (QUERY_HEADER_LEN + OLD_HEADER_LEN); - buf += OLD_HEADER_LEN; + status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET); + data_len-= status_vars_len; + DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u", + (uint) status_vars_len)); + tmp-= 2; } - else + /* we have parsed everything we know in the post header */ +#ifndef DBUG_OFF + if (tmp) /* this is probably a master newer than us */ + DBUG_PRINT("info", ("Query_log_event has longer post header than we know\ + (%d more bytes)", tmp)); +#endif + + /* variable-part: the status vars; only in MySQL 5.0 */ + + start= (char*) (buf+post_header_len); + end= (char*) (start+status_vars_len); + for (const uchar* pos= (const uchar*) start; pos < (const uchar*) end;) { - if ((uint)event_len < QUERY_EVENT_OVERHEAD) - return; - data_len = event_len - QUERY_EVENT_OVERHEAD; - buf += LOG_EVENT_HEADER_LEN; + switch (*pos++) { + case Q_FLAGS2_CODE: + flags2_inited= 1; + flags2= uint4korr(pos); + DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", flags2)); + pos+= 4; + break; + case Q_SQL_MODE_CODE: + { +#ifndef DBUG_OFF + char buff[22]; +#endif + sql_mode_inited= 1; + sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is ulonglong + DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s", + llstr(sql_mode, buff))); + pos+= 8; + break; + } + case Q_CATALOG_CODE: + catalog_len= *pos; + if (catalog_len) + catalog= (char*) pos+1; // Will be copied later + pos+= catalog_len+2; + break; + case Q_AUTO_INCREMENT: + auto_increment_increment= uint2korr(pos); + auto_increment_offset= uint2korr(pos+2); + pos+= 4; + break; + default: + /* That's why you must write status vars in growing order of code */ + DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ + code: %u), skipping the rest of them", (uint) *(pos-1))); + pos= (const uchar*) end; // Break look + } } - - exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET); - error_code = uint2korr(buf + Q_ERR_CODE_OFFSET); - - if (!(data_buf = (char*) my_malloc(data_len + 1, MYF(MY_WME)))) - return; - - memcpy(data_buf, buf + Q_DATA_OFFSET, data_len); - slave_proxy_id= thread_id= uint4korr(buf + Q_THREAD_ID_OFFSET); - db = data_buf; - db_len = (uint)buf[Q_DB_LEN_OFFSET]; - query=data_buf + db_len + 1; - q_len = data_len - 1 - db_len; - *((char*)query+q_len) = 0; + + /* A 2nd variable part; this is common to all versions */ + + if (!(start= data_buf = (char*) my_malloc(catalog_len + data_len +2, MYF(MY_WME)))) + DBUG_VOID_RETURN; + if (catalog) // If catalog is given + { + memcpy((char*) start, catalog, catalog_len+1); // Copy name and end \0 + catalog= start; + start+= catalog_len+1; + } + memcpy((char*) start, end, data_len); // Copy db and query + ((char*) start)[data_len]= '\0'; // End query with \0 (For safetly) + db= start; + query= start + db_len + 1; + q_len= data_len - db_len -1; + /* This is used to detect wrong parsing. Could be removed in the future. */ + DBUG_PRINT("info", ("catalog: '%s' len: %u db: '%s' len: %u q_len: %lu", + catalog, (uint) catalog_len, db, (uint) db_len,q_len)); + DBUG_VOID_RETURN; } @@ -937,9 +1244,14 @@ Query_log_event::Query_log_event(const char* buf, int event_len, */ #ifdef MYSQL_CLIENT -void Query_log_event::print(FILE* file, bool short_form, char* last_db) +void Query_log_event::print(FILE* file, bool short_form, + LAST_EVENT_INFO* last_event_info) { + // TODO: print the catalog ?? char buff[40],*end; // Enough for SET TIMESTAMP + bool different_db= 1; + uint32 tmp; + if (!short_form) { print_header(file); @@ -947,12 +1259,10 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) (ulong) thread_id, (ulong) exec_time, error_code); } - bool different_db= 1; - - if (db && last_db) + if (db) { - if (different_db= memcmp(last_db, db, db_len + 1)) - memcpy(last_db, db, db_len + 1); + if ((different_db = memcmp(last_event_info->db, db, db_len + 1))) + memcpy(last_event_info->db, db, db_len + 1); } if (db && db[0] && different_db) @@ -963,8 +1273,76 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME)); if (flags & LOG_EVENT_THREAD_SPECIFIC_F) fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id); + /* + Now the session variables; + it's more efficient to pass SQL_MODE as a number instead of a + comma-separated list. + FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only + variables (they have no global version; they're not listed in sql_class.h), + The tests below work for pure binlogs or pure relay logs. Won't work for + mixed relay logs but we don't create mixed relay logs (that is, there is no + relay log with a format change except within the 3 first events, which + mysqlbinlog handles gracefully). So this code should always be good. + */ + + if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */ + { + /* tmp is a bitmask of bits which have changed. */ + if (likely(last_event_info->flags2_inited)) + /* All bits which have changed */ + tmp= (last_event_info->flags2) ^ flags2; + else /* that's the first Query event we read */ + { + last_event_info->flags2_inited= 1; + tmp= ~((uint32)0); /* all bits have changed */ + } + + if (unlikely(tmp)) /* some bits have changed */ + { + bool need_comma= 0; + fprintf(file, "SET "); + print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2, + "@@session.foreign_key_checks", &need_comma); + print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2, + "@@session.sql_auto_is_null", &need_comma); + print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2, + "@@session.unique_checks", &need_comma); + fprintf(file,";\n"); + last_event_info->flags2= flags2; + } + } + + /* + If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to print + (remember we don't produce mixed relay logs so there cannot be 5.0 events + before that one so there is nothing to reset). + */ + + if (likely(sql_mode_inited)) + { + if (unlikely(!last_event_info->sql_mode_inited)) /* first Query event */ + { + last_event_info->sql_mode_inited= 1; + /* force a difference to force write */ + last_event_info->sql_mode= ~sql_mode; + } + if (unlikely(last_event_info->sql_mode != sql_mode)) + { + fprintf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode); + last_event_info->sql_mode= sql_mode; + } + } + if (last_event_info->auto_increment_increment != auto_increment_increment || + last_event_info->auto_increment_offset != auto_increment_offset) + { + fprintf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n", + auto_increment_increment,auto_increment_offset); + last_event_info->auto_increment_increment= auto_increment_increment; + last_event_info->auto_increment_offset= auto_increment_offset; + } + my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)); - fprintf(file, ";\n"); + fputs(";\n", file); } #endif /* MYSQL_CLIENT */ @@ -977,20 +1355,30 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db) int Query_log_event::exec_event(struct st_relay_log_info* rli) { int expected_error,actual_error= 0; - thd->db_length= db_len; - thd->db= (char*) rewrite_db(db, &thd->db_length); + /* + Colleagues: please never free(thd->catalog) in MySQL. This would lead to + bugs as here thd->catalog is a part of an alloced block, not an entire + alloced block (see Query_log_event::exec_event()). Same for thd->db. + Thank you. + */ + thd->catalog= (char*) catalog; + thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed + thd->variables.auto_increment_increment= auto_increment_increment; + thd->variables.auto_increment_offset= auto_increment_offset; /* - InnoDB internally stores the master log position it has processed so far; - position to store is of the END of the current log event. + InnoDB internally stores the master log position it has executed so far, + i.e. the position just after the COMMIT event. + When InnoDB will want to store, the positions in rli won't have + been updated yet, so group_master_log_* will point to old BEGIN + and event_master_log* will point to the beginning of current COMMIT. + But log_pos of the COMMIT Query event is what we want, i.e. the pos of the + END of the current log event (COMMIT). We save it in rli so that InnoDB can + access it. */ -#if MYSQL_VERSION_ID < 50000 - rli->future_group_master_log_pos= log_pos + get_event_len() - - (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); -#else - /* In 5.0 we store the end_log_pos in the relay log so no problem */ rli->future_group_master_log_pos= log_pos; -#endif + DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos)); + clear_all_errors(thd, rli); if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) @@ -1002,9 +1390,33 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->variables.pseudo_thread_id= thread_id; // for temp tables - mysql_log.write(thd,COM_QUERY,"%s",thd->query); DBUG_PRINT("query",("%s",thd->query)); + + if (flags2_inited) + /* + all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG must + take their value from flags2. + */ + thd->options= flags2|(thd->options & ~(ulong)OPTIONS_WRITTEN_TO_BIN_LOG); + /* + else, we are in a 3.23/4.0 binlog; we previously received a + Rotate_log_event which reset thd->options and sql_mode, so nothing to do. + */ + + /* + We do not replicate IGNORE_DIR_IN_CREATE. That is, if the master is a + slave which runs with SQL_MODE=IGNORE_DIR_IN_CREATE, this should not + force us to ignore the dir too. Imagine you are a ring of machines, and + one has a disk problem so that you temporarily need IGNORE_DIR_IN_CREATE + on this machine; you don't want it to propagate elsewhere (you don't want + all slaves to start ignoring the dirs). + */ + if (sql_mode_inited) + thd->variables.sql_mode= + (ulong) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) | + (sql_mode & ~(ulong) MODE_NO_DIR_IN_CREATE)); + if (ignored_error_code((expected_error= error_code)) || !check_expected_error(thd,rli,expected_error)) mysql_parse(thd, thd->query, q_len); @@ -1032,20 +1444,20 @@ START SLAVE; . Query: '%s'", expected_error, thd->query); } goto end; } - + /* If we expected a non-zero error code, and we don't get the same error code, and none of them should be ignored. */ DBUG_PRINT("info",("expected_error: %d last_errno: %d", - expected_error, thd->net.last_errno)); + expected_error, thd->net.last_errno)); if ((expected_error != (actual_error= thd->net.last_errno)) && - expected_error && - !ignored_error_code(actual_error) && - !ignored_error_code(expected_error)) + expected_error && + !ignored_error_code(actual_error) && + !ignored_error_code(expected_error)) { slave_print_error(rli, 0, - "\ + "\ Query caused different errors on master and slave. \ Error on master: '%s' (%d), Error on slave: '%s' (%d). \ Default database: '%s'. Query: '%s'", @@ -1053,14 +1465,14 @@ Default database: '%s'. Query: '%s'", expected_error, actual_error ? thd->net.last_error: "no error", actual_error, - print_slave_db_safe(thd->db), query); + print_slave_db_safe(db), query); thd->query_error= 1; } /* If we get the same error code as expected, or they should be ignored. */ else if (expected_error == actual_error || - ignored_error_code(actual_error)) + ignored_error_code(actual_error)) { DBUG_PRINT("info",("error ignored")); clear_all_errors(thd, rli); @@ -1077,11 +1489,43 @@ Default database: '%s'. Query: '%s'", print_slave_db_safe(thd->db), query); thd->query_error= 1; } + + /* + TODO: compare the values of "affected rows" around here. Something + like: + if ((uint32) affected_in_event != (uint32) affected_on_slave) + { + sql_print_error("Slave: did not get the expected number of affected \ + rows running query from master - expected %d, got %d (this numbers \ + should have matched modulo 4294967296).", 0, ...); + thd->query_error = 1; + } + We may also want an option to tell the slave to ignore "affected" + mismatch. This mismatch could be implemented with a new ER_ code, and + to ignore it you would use --slave-skip-errors... + + To do the comparison we need to know the value of "affected" which the + above mysql_parse() computed. And we need to know the value of + "affected" in the master's binlog. Both will be implemented later. The + important thing is that we now have the format ready to log the values + of "affected" in the binlog. So we can release 5.0.0 before effectively + logging "affected" and effectively comparing it. + */ } /* End of if (db_ok(... */ end: VOID(pthread_mutex_lock(&LOCK_thread_count)); - thd->db= 0; // prevent db from being freed + /* + Probably we have set thd->query, thd->db, thd->catalog to point to places + in the data_buf of this event. Now the event is going to be deleted + probably, so data_buf will be freed, so the thd->... listed above will be + pointers to freed memory. + So we must set them to 0, so that those bad pointers values are not later + used. Note that "cleanup" queries (automatic DO RELEASE_LOCK() and DROP + TEMPORARY TABLE don't suffer from these assignments to 0 as DROP TEMPORARY + TABLE uses the db.table syntax). + */ + thd->db= thd->catalog= 0; // prevent db from being freed thd->query= 0; // just to be sure thd->query_length= thd->db_length =0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); @@ -1094,22 +1538,30 @@ end: updating query. */ return (thd->query_error ? thd->query_error : - (thd->one_shot_set ? (rli->inc_event_relay_log_pos(get_event_len()),0) : + (thd->one_shot_set ? (rli->inc_event_relay_log_pos(),0) : Log_event::exec_event(rli))); } #endif /************************************************************************** - Start_log_event methods + Start_log_event_v3 methods **************************************************************************/ +#ifndef MYSQL_CLIENT +Start_log_event_v3::Start_log_event_v3() :Log_event(), binlog_version(BINLOG_VERSION), artificial_event(0) +{ + created= when; + memcpy(server_version, ::server_version, ST_SERVER_VER_LEN); +} +#endif + /* - Start_log_event::pack_info() + Start_log_event_v3::pack_info() */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -void Start_log_event::pack_info(Protocol *protocol) +void Start_log_event_v3::pack_info(Protocol *protocol) { char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos; pos= strmov(buf, "Server ver: "); @@ -1122,57 +1574,69 @@ void Start_log_event::pack_info(Protocol *protocol) /* - Start_log_event::print() + Start_log_event_v3::print() */ #ifdef MYSQL_CLIENT -void Start_log_event::print(FILE* file, bool short_form, char* last_db) +void Start_log_event_v3::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { - if (short_form) - return; - - print_header(file); - fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version, - server_version); - print_timestamp(file); - if (created) - fprintf(file," at startup"); - fputc('\n', file); + if (!short_form) + { + print_header(file); + fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version, + server_version); + print_timestamp(file); + if (created) + fprintf(file," at startup"); + fputc('\n', file); + } +#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND + /* + This is for mysqlbinlog: like in replication, we want to delete the stale + tmp files left by an unclean shutdown of mysqld (temporary tables). Probably + this can be done with RESET CONNECTION (syntax to be defined). + */ + fprintf(file,"RESET CONNECTION;\n"); +#endif fflush(file); } #endif /* MYSQL_CLIENT */ /* - Start_log_event::Start_log_event() + Start_log_event_v3::Start_log_event_v3() */ -Start_log_event::Start_log_event(const char* buf, - bool old_format) - :Log_event(buf, old_format) +Start_log_event_v3::Start_log_event_v3(const char* buf, + const Format_description_log_event* description_event) + :Log_event(buf, description_event) { - buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; - binlog_version = uint2korr(buf+ST_BINLOG_VER_OFFSET); + buf+= description_event->common_header_len; + binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET); memcpy(server_version, buf+ST_SERVER_VER_OFFSET, ST_SERVER_VER_LEN); - created = uint4korr(buf+ST_CREATED_OFFSET); + created= uint4korr(buf+ST_CREATED_OFFSET); + /* We use log_pos to mark if this was an artificial event or not */ + artificial_event= (log_pos == 0); } /* - Start_log_event::write_data() + Start_log_event_v3::write() */ -int Start_log_event::write_data(IO_CACHE* file) +bool Start_log_event_v3::write(IO_CACHE* file) { - char buff[START_HEADER_LEN]; + char buff[START_V3_HEADER_LEN]; int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version); memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN); int4store(buff + ST_CREATED_OFFSET,created); - return (my_b_safe_write(file, (byte*) buff, sizeof(buff)) ? -1 : 0); + return (write_header(file, sizeof(buff)) || + my_b_safe_write(file, (byte*) buff, sizeof(buff))); } + /* - Start_log_event::exec_event() + Start_log_event_v3::exec_event() The master started @@ -1191,23 +1655,29 @@ int Start_log_event::write_data(IO_CACHE* file) */ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -int Start_log_event::exec_event(struct st_relay_log_info* rli) +int Start_log_event_v3::exec_event(struct st_relay_log_info* rli) { - DBUG_ENTER("Start_log_event::exec_event"); - + DBUG_ENTER("Start_log_event_v3::exec_event"); /* If the I/O thread has not started, mi->old_format is BINLOG_FORMAT_CURRENT (that's what the MASTER_INFO constructor does), so the test below is not perfect at all. */ - switch (rli->mi->old_format) { - case BINLOG_FORMAT_CURRENT: - /* - This is 4.x, so a Start_log_event is only at master startup, - so we are sure the master has restarted and cleared his temp tables. + switch (rli->relay_log.description_event_for_exec->binlog_version) + { + case 3: + case 4: + /* + This can either be 4.x (then a Start_log_event_v3 is only at master + startup so we are sure the master has restarted and cleared his temp + tables; the event always has 'created'>0) or 5.0 (then we have to test + 'created'). */ - close_temporary_tables(thd); - cleanup_load_tmpdir(); + if (created) + { + close_temporary_tables(thd); + cleanup_load_tmpdir(); + } /* As a transaction NEVER spans on 2 or more binlogs: if we have an active transaction at this point, the master died while @@ -1215,8 +1685,12 @@ int Start_log_event::exec_event(struct st_relay_log_info* rli) cache to the binlog. As the write was started, the transaction had been committed on the master, so we lack of information to replay this transaction on the slave; all we can do is stop with error. + Note: this event could be sent by the master to inform us of the format + of its binlog; in other words maybe it is not at its original place when + it comes to us; we'll know this by checking log_pos ("artificial" events + have log_pos == 0). */ - if (thd->options & OPTION_BEGIN) + if (!artificial_event && (thd->options & OPTION_BEGIN)) { slave_print_error(rli, 0, "\ Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. \ @@ -1230,33 +1704,274 @@ binary log."); Now the older formats; in that case load_tmpdir is cleaned up by the I/O thread. */ - case BINLOG_FORMAT_323_LESS_57: - /* - Cannot distinguish a Start_log_event generated at master startup and - one generated by master FLUSH LOGS, so cannot be sure temp tables - have to be dropped. So do nothing. - */ - break; - case BINLOG_FORMAT_323_GEQ_57: + case 1: + if (strncmp(rli->relay_log.description_event_for_exec->server_version, + "3.23.57",7) >= 0 && created) + { + /* + Can distinguish, based on the value of 'created': this event was + generated at master startup. + */ + close_temporary_tables(thd); + } /* - Can distinguish, based on the value of 'created', - which was generated at master startup. + Otherwise, can't distinguish a Start_log_event generated at + master startup and one generated by master FLUSH LOGS, so cannot + be sure temp tables have to be dropped. So do nothing. */ - if (created) - close_temporary_tables(thd); break; default: /* this case is impossible */ - return 1; + DBUG_RETURN(1); } - DBUG_RETURN(Log_event::exec_event(rli)); } #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */ -/************************************************************************** - Load_log_event methods -**************************************************************************/ +/*************************************************************************** + Format_description_log_event methods +****************************************************************************/ + +/* + Format_description_log_event 1st ctor. + + SYNOPSIS + Format_description_log_event::Format_description_log_event + binlog_version the binlog version for which we want to build + an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x + x>=2 and 4.1) or 4 (MySQL 5.0). Note that the + old 4.0 (binlog version 2) is not supported; + it should not be used for replication with + 5.0. + + DESCRIPTION + Ctor. Can be used to create the event to write to the binary log (when the + server starts or when FLUSH LOGS), or to create artificial events to parse + binlogs from MySQL 3.23 or 4.x. + When in a client, only the 2nd use is possible. + + TODO + Update this code with the new event for LOAD DATA, once they are pushed (in + 4.1 or 5.0). If it's in 5.0, only the "case 4" block should be updated. + +*/ + +Format_description_log_event:: +Format_description_log_event(uint8 binlog_ver, + const char* server_ver) + :Start_log_event_v3() +{ + created= when; + binlog_version= binlog_ver; + switch (binlog_ver) { + case 4: /* MySQL 5.0 */ + memcpy(server_version, ::server_version, ST_SERVER_VER_LEN); + common_header_len= LOG_EVENT_HEADER_LEN; + number_of_event_types= LOG_EVENT_TYPES; + /* we'll catch my_malloc() error in is_valid() */ + post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8), + MYF(0)); + /* + This long list of assignments is not beautiful, but I see no way to + make it nicer, as the right members are #defines, not array members, so + it's impossible to write a loop. + */ + if (post_header_len) + { + post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN; + post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN; + post_header_len[STOP_EVENT-1]= 0; + post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN; + post_header_len[INTVAR_EVENT-1]= 0; + post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN; + post_header_len[SLAVE_EVENT-1]= 0; + post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN; + post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN; + post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN; + post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN; + post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1]; + post_header_len[RAND_EVENT-1]= 0; + post_header_len[USER_VAR_EVENT-1]= 0; + post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN; + } + break; + + case 1: /* 3.23 */ + case 3: /* 4.0.x x>=2 */ + /* + We build an artificial (i.e. not sent by the master) event, which + describes what those old master versions send. + */ + if (binlog_ver==1) + strmov(server_version, server_ver ? server_ver : "3.23"); + else + strmov(server_version, server_ver ? server_ver : "4.0"); + common_header_len= binlog_ver==1 ? OLD_HEADER_LEN : + LOG_EVENT_MINIMAL_HEADER_LEN; + /* + The first new event in binlog version 4 is Format_desc. So any event type + after that does not exist in older versions. We use the events known by + version 3, even if version 1 had only a subset of them (this is not a + problem: it uses a few bytes for nothing but unifies code; it does not + make the slave detect less corruptions). + */ + number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1; + post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8), + MYF(0)); + if (post_header_len) + { + post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN; + post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN; + post_header_len[STOP_EVENT-1]= 0; + post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN; + post_header_len[INTVAR_EVENT-1]= 0; + post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN; + post_header_len[SLAVE_EVENT-1]= 0; + post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN; + post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN; + post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN; + post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN; + post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1]; + post_header_len[RAND_EVENT-1]= 0; + post_header_len[USER_VAR_EVENT-1]= 0; + } + break; + default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */ + post_header_len= 0; /* will make is_valid() fail */ + break; + } +} + + +/* + The problem with this constructor is that the fixed header may have a + length different from this version, but we don't know this length as we + have not read the Format_description_log_event which says it, yet. This + length is in the post-header of the event, but we don't know where the + post-header starts. + So this type of event HAS to: + - either have the header's length at the beginning (in the header, at a + fixed position which will never be changed), not in the post-header. That + would make the header be "shifted" compared to other events. + - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future + versions, so that we know for sure. + I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because + it is sent before Format_description_log_event). +*/ + +Format_description_log_event:: +Format_description_log_event(const char* buf, + uint event_len, + const + Format_description_log_event* + description_event) + :Start_log_event_v3(buf, description_event) +{ + DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)"); + buf+= LOG_EVENT_MINIMAL_HEADER_LEN; + if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN) + DBUG_VOID_RETURN; /* sanity check */ + number_of_event_types= + event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1); + DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d", + common_header_len, number_of_event_types)); + /* If alloc fails, we'll detect it in is_valid() */ + post_header_len= (uint8*) my_memdup((byte*)buf+ST_COMMON_HEADER_LEN_OFFSET+1, + number_of_event_types* + sizeof(*post_header_len), + MYF(0)); + DBUG_VOID_RETURN; +} + + +bool Format_description_log_event::write(IO_CACHE* file) +{ + /* + We don't call Start_log_event_v3::write() because this would make 2 + my_b_safe_write(). + */ + byte buff[FORMAT_DESCRIPTION_HEADER_LEN]; + int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version); + memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN); + int4store(buff + ST_CREATED_OFFSET,created); + buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN; + memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (byte*) post_header_len, + LOG_EVENT_TYPES); + return (write_header(file, sizeof(buff)) || + my_b_safe_write(file, buff, sizeof(buff))); +} + +/* + SYNOPSIS + Format_description_log_event::exec_event() + + IMPLEMENTATION + Save the information which describes the binlog's format, to be able to + read all coming events. + Call Start_log_event_v3::exec_event(). +*/ + +#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) +int Format_description_log_event::exec_event(struct st_relay_log_info* rli) +{ + DBUG_ENTER("Format_description_log_event::exec_event"); + + /* save the information describing this binlog */ + delete rli->relay_log.description_event_for_exec; + rli->relay_log.description_event_for_exec= this; + + /* + If this event comes from ourselves, there is no cleaning task to perform, + we don't call Start_log_event_v3::exec_event() (this was just to update the + log's description event). + */ + if (server_id == (uint32) ::server_id) + { + /* + Do not modify rli->group_master_log_pos, as this event did not exist on + the master. That is, just update the *relay log* coordinates; this is + done by passing log_pos=0 to inc_group_relay_log_pos, like we do in + Stop_log_event::exec_event(). + If in a transaction, don't touch group_* coordinates. + */ + if (thd->options & OPTION_BEGIN) + rli->inc_event_relay_log_pos(); + else + { + rli->inc_group_relay_log_pos(0); + flush_relay_log_info(rli); + } + DBUG_RETURN(0); + } + + /* + If the event was not requested by the slave i.e. the master sent it while + the slave asked for a position >4, the event will make + rli->group_master_log_pos advance. Say that the slave asked for position + 1000, and the Format_desc event's end is 95. Then in the beginning of + replication rli->group_master_log_pos will be 0, then 95, then jump to first + really asked event (which is >95). So this is ok. + */ + DBUG_RETURN(Start_log_event_v3::exec_event(rli)); +} +#endif + + /************************************************************************** + Load_log_event methods + General note about Load_log_event: the binlogging of LOAD DATA INFILE is + going to be changed in 5.0 (or maybe in 4.1; not decided yet). + However, the 5.0 slave could still have to read such events (from a 4.x + master), convert them (which just means maybe expand the header, when 5.0 + servers have a UID in events) (remember that whatever is after the header + will be like in 4.x, as this event's format is not modified in 5.0 as we + will use new types of events to log the new LOAD DATA INFILE features). + To be able to read/convert, we just need to not assume that the common + header is of length LOG_EVENT_HEADER_LEN (we must use the description + event). + Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE + between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the + positions displayed in SHOW SLAVE STATUS then are fine too). + **************************************************************************/ /* Load_log_event::pack_info() @@ -1363,7 +2078,7 @@ void Load_log_event::pack_info(Protocol *protocol) Load_log_event::write_data_header() */ -int Load_log_event::write_data_header(IO_CACHE* file) +bool Load_log_event::write_data_header(IO_CACHE* file) { char buf[LOAD_HEADER_LEN]; int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id); @@ -1372,7 +2087,7 @@ int Load_log_event::write_data_header(IO_CACHE* file) buf[L_TBL_LEN_OFFSET] = (char)table_name_len; buf[L_DB_LEN_OFFSET] = (char)db_len; int4store(buf + L_NUM_FIELDS_OFFSET, num_fields); - return my_b_safe_write(file, (byte*)buf, LOAD_HEADER_LEN); + return my_b_safe_write(file, (byte*)buf, LOAD_HEADER_LEN) != 0; } @@ -1380,7 +2095,7 @@ int Load_log_event::write_data_header(IO_CACHE* file) Load_log_event::write_data_body() */ -int Load_log_event::write_data_body(IO_CACHE* file) +bool Load_log_event::write_data_body(IO_CACHE* file) { if (sql_ex.write_data(file)) return 1; @@ -1483,6 +2198,7 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, } #endif /* !MYSQL_CLIENT */ + /* Load_log_event::Load_log_event() @@ -1491,15 +2207,25 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex, constructed event. */ -Load_log_event::Load_log_event(const char *buf, int event_len, - bool old_format) - :Log_event(buf, old_format), num_fields(0), fields(0), - field_lens(0), field_block_len(0), +Load_log_event::Load_log_event(const char *buf, uint event_len, + const Format_description_log_event *description_event) + :Log_event(buf, description_event), num_fields(0), fields(0), + field_lens(0),field_block_len(0), table_name(0), db(0), fname(0), local_fname(FALSE) { DBUG_ENTER("Load_log_event"); - if (event_len) // derived class, will call copy_log_event() itself - copy_log_event(buf, event_len, old_format); + /* + I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0, + 4.0->5.0 and 5.0->5.0 and it works. + */ + if (event_len) + copy_log_event(buf, event_len, + ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ? + LOAD_HEADER_LEN + + description_event->common_header_len : + LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN), + description_event); + /* otherwise it's a derived class, will call copy_log_event() itself */ DBUG_VOID_RETURN; } @@ -1509,14 +2235,14 @@ Load_log_event::Load_log_event(const char *buf, int event_len, */ int Load_log_event::copy_log_event(const char *buf, ulong event_len, - bool old_format) + int body_offset, + const Format_description_log_event *description_event) { + DBUG_ENTER("Load_log_event::copy_log_event"); uint data_len; char* buf_end = (char*)buf + event_len; - uint header_len= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; - const char* data_head = buf + header_len; - DBUG_ENTER("Load_log_event::copy_log_event"); - + /* this is the beginning of the post-header */ + const char* data_head = buf + description_event->common_header_len; slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET); exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET); skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET); @@ -1524,21 +2250,17 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, db_len = (uint)data_head[L_DB_LEN_OFFSET]; num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET); - int body_offset = ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ? - LOAD_HEADER_LEN + header_len : - get_data_body_offset()); - if ((int) event_len < body_offset) DBUG_RETURN(1); /* Sql_ex.init() on success returns the pointer to the first byte after the sql_ex structure, which is the start of field lengths array. */ - if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset, - buf_end, - buf[EVENT_TYPE_OFFSET] != LOAD_EVENT))) + if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset, + buf_end, + buf[EVENT_TYPE_OFFSET] != LOAD_EVENT))) DBUG_RETURN(1); - + data_len = event_len - body_offset; if (num_fields > data_len) // simple sanity check against corruption DBUG_RETURN(1); @@ -1551,6 +2273,12 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, fname = db + db_len + 1; fname_len = strlen(fname); // null termination is accomplished by the caller doing buf[event_len]=0 + + /* + In 5.0 this event will have the same format, as we are planning to log LOAD + DATA INFILE in a completely different way (as a plain-text query) since 4.1 + or 5.0 (Dmitri's WL#874) + */ DBUG_RETURN(0); } @@ -1560,13 +2288,13 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, */ #ifdef MYSQL_CLIENT -void Load_log_event::print(FILE* file, bool short_form, char* last_db) +void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { - print(file, short_form, last_db, 0); + print(file, short_form, last_event_info, 0); } -void Load_log_event::print(FILE* file, bool short_form, char* last_db, +void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool commented) { DBUG_ENTER("Load_log_event::print"); @@ -1578,7 +2306,7 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db, } bool different_db= 1; - if (db && last_db) + if (db) { /* If the database is different from the one of the previous statement, we @@ -1586,9 +2314,9 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db, But if commented, the "use" is going to be commented so we should not update the last_db. */ - if ((different_db= memcmp(last_db, db, db_len + 1)) && + if ((different_db= memcmp(last_event_info->db, db, db_len + 1)) && !commented) - memcpy(last_db, db, db_len + 1); + memcpy(last_event_info->db, db, db_len + 1); } if (db && db[0] && different_db) @@ -1715,15 +2443,12 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, mysql_init_query(thd, 0, 0); if (!use_rli_only_for_errors) { -#if MYSQL_VERSION_ID < 50000 - rli->future_group_master_log_pos= log_pos + get_event_len() - - (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); -#else + /* Saved for InnoDB, see comment in Query_log_event::exec_event() */ rli->future_group_master_log_pos= log_pos; -#endif + DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos)); } - - /* + + /* We test replicate_*_db rules. Note that we have already prepared the file to load, even if we are going to ignore and delete it now. So it is possible that we did a lot of disk writes for nothing. In other words, a @@ -1832,7 +2557,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, thd->net.pkt_nr = net->pkt_nr; } if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0, - TL_WRITE)) + TL_WRITE, 0)) thd->query_error = 1; if (thd->cuted_fields) { @@ -1863,7 +2588,7 @@ Slave: load data infile on table '%s' at log position %s in log \ thd->net.vio = 0; char *save_db= thd->db; VOID(pthread_mutex_lock(&LOCK_thread_count)); - thd->db= 0; + thd->db= thd->catalog= 0; thd->query= 0; thd->query_length= thd->db_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); @@ -1930,17 +2655,17 @@ void Rotate_log_event::pack_info(Protocol *protocol) */ #ifdef MYSQL_CLIENT -void Rotate_log_event::print(FILE* file, bool short_form, char* last_db) +void Rotate_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { char buf[22]; + if (short_form) return; - print_header(file); fprintf(file, "\tRotate to "); if (new_log_ident) my_fwrite(file, (byte*) new_log_ident, (uint)ident_len, - MYF(MY_NABP | MY_WME)); + MYF(MY_NABP | MY_WME)); fprintf(file, " pos: %s", llstr(pos, buf)); fputc('\n', file); fflush(file); @@ -1952,31 +2677,22 @@ void Rotate_log_event::print(FILE* file, bool short_form, char* last_db) Rotate_log_event::Rotate_log_event() */ -Rotate_log_event::Rotate_log_event(const char* buf, int event_len, - bool old_format) - :Log_event(buf, old_format),new_log_ident(NULL),alloced(0) +Rotate_log_event::Rotate_log_event(const char* buf, uint event_len, + const Format_description_log_event* description_event) + :Log_event(buf, description_event) ,new_log_ident(NULL),alloced(0) { + DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)"); // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET - int header_size = (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; + uint8 header_size= description_event->common_header_len; + uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1]; uint ident_offset; - DBUG_ENTER("Rotate_log_event"); - if (event_len < header_size) DBUG_VOID_RETURN; - buf += header_size; - if (old_format) - { - ident_len = (uint)(event_len - OLD_HEADER_LEN); - pos = 4; - ident_offset = 0; - } - else - { - ident_len = (uint)(event_len - ROTATE_EVENT_OVERHEAD); - pos = uint8korr(buf + R_POS_OFFSET); - ident_offset = ROTATE_HEADER_LEN; - } + pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4; + ident_len = (uint)(event_len - + (header_size+post_header_len)); + ident_offset = post_header_len; set_if_smaller(ident_len,FN_REFLEN-1); if (!(new_log_ident= my_strdup_with_length((byte*) buf + ident_offset, @@ -1989,29 +2705,31 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len, /* - Rotate_log_event::write_data() + Rotate_log_event::write() */ -int Rotate_log_event::write_data(IO_CACHE* file) +bool Rotate_log_event::write(IO_CACHE* file) { char buf[ROTATE_HEADER_LEN]; int8store(buf + R_POS_OFFSET, pos); - return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) || - my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len)); + return (write_header(file, ROTATE_HEADER_LEN + ident_len) || + my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) || + my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len)); } /* Rotate_log_event::exec_event() - Got a rotate log even from the master + Got a rotate log event from the master IMPLEMENTATION This is mainly used so that we can later figure out the logname and position for the master. - We can't rotate the slave as this will cause infinitive rotations + We can't rotate the slave's BINlog as this will cause infinitive rotations in a A -> B -> A setup. + The NOTES below is a wrong comment which will disappear when 4.1 is merged. RETURN VALUES 0 ok @@ -2023,7 +2741,7 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) DBUG_ENTER("Rotate_log_event::exec_event"); pthread_mutex_lock(&rli->data_lock); - rli->event_relay_log_pos += get_event_len(); + rli->event_relay_log_pos= my_b_tell(rli->cur_log); /* If we are in a transaction: the only normal case is when the I/O thread was copying a big transaction, then it was stopped and restarted: we have this @@ -2035,15 +2753,28 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) COMMIT or ROLLBACK In that case, we don't want to touch the coordinates which correspond to the beginning of the transaction. + Starting from 5.0.0, there also are some rotates from the slave itself, in + the relay log. */ if (!(thd->options & OPTION_BEGIN)) { memcpy(rli->group_master_log_name, new_log_ident, ident_len+1); rli->notify_group_master_log_name_update(); - rli->group_master_log_pos = pos; - rli->group_relay_log_pos = rli->event_relay_log_pos; - DBUG_PRINT("info", ("group_master_log_pos: %lu", + rli->group_master_log_pos= pos; + rli->group_relay_log_pos= rli->event_relay_log_pos; + DBUG_PRINT("info", ("group_master_log_name: '%s' group_master_log_pos:\ +%lu", + rli->group_master_log_name, (ulong) rli->group_master_log_pos)); + /* + Reset thd->options and sql_mode, because this could be the signal of a + master's downgrade from 5.0 to 4.0. + However, no need to reset description_event_for_exec: indeed, if the next + master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next + master is 4.0 then the events are in the slave's format (conversion). + */ + set_slave_thread_options(thd); + thd->variables.sql_mode= global_system_variables.sql_mode; } pthread_mutex_unlock(&rli->data_lock); pthread_cond_broadcast(&rli->data_cond); @@ -2077,12 +2808,13 @@ void Intvar_log_event::pack_info(Protocol *protocol) Intvar_log_event::Intvar_log_event() */ -Intvar_log_event::Intvar_log_event(const char* buf, bool old_format) - :Log_event(buf, old_format) +Intvar_log_event::Intvar_log_event(const char* buf, + const Format_description_log_event* description_event) + :Log_event(buf, description_event) { - buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; - type = buf[I_TYPE_OFFSET]; - val = uint8korr(buf+I_VAL_OFFSET); + buf+= description_event->common_header_len; + type= buf[I_TYPE_OFFSET]; + val= uint8korr(buf+I_VAL_OFFSET); } @@ -2101,15 +2833,16 @@ const char* Intvar_log_event::get_var_type_name() /* - Intvar_log_event::write_data() + Intvar_log_event::write() */ -int Intvar_log_event::write_data(IO_CACHE* file) +bool Intvar_log_event::write(IO_CACHE* file) { - char buf[9]; - buf[I_TYPE_OFFSET] = type; + byte buf[9]; + buf[I_TYPE_OFFSET]= (byte) type; int8store(buf + I_VAL_OFFSET, val); - return my_b_safe_write(file, (byte*) buf, sizeof(buf)); + return (write_header(file, sizeof(buf)) || + my_b_safe_write(file, buf, sizeof(buf))); } @@ -2118,7 +2851,8 @@ int Intvar_log_event::write_data(IO_CACHE* file) */ #ifdef MYSQL_CLIENT -void Intvar_log_event::print(FILE* file, bool short_form, char* last_db) +void Intvar_log_event::print(FILE* file, bool short_form, + LAST_EVENT_INFO* last_event_info) { char llbuff[22]; const char *msg; @@ -2161,7 +2895,7 @@ int Intvar_log_event::exec_event(struct st_relay_log_info* rli) thd->next_insert_id = val; break; } - rli->inc_event_relay_log_pos(get_event_len()); + rli->inc_event_relay_log_pos(); return 0; } #endif @@ -2184,26 +2918,28 @@ void Rand_log_event::pack_info(Protocol *protocol) #endif -Rand_log_event::Rand_log_event(const char* buf, bool old_format) - :Log_event(buf, old_format) +Rand_log_event::Rand_log_event(const char* buf, + const Format_description_log_event* description_event) + :Log_event(buf, description_event) { - buf += (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; - seed1 = uint8korr(buf+RAND_SEED1_OFFSET); - seed2 = uint8korr(buf+RAND_SEED2_OFFSET); + buf+= description_event->common_header_len; + seed1= uint8korr(buf+RAND_SEED1_OFFSET); + seed2= uint8korr(buf+RAND_SEED2_OFFSET); } -int Rand_log_event::write_data(IO_CACHE* file) +bool Rand_log_event::write(IO_CACHE* file) { - char buf[16]; + byte buf[16]; int8store(buf + RAND_SEED1_OFFSET, seed1); int8store(buf + RAND_SEED2_OFFSET, seed2); - return my_b_safe_write(file, (byte*) buf, sizeof(buf)); + return (write_header(file, sizeof(buf)) || + my_b_safe_write(file, buf, sizeof(buf))); } #ifdef MYSQL_CLIENT -void Rand_log_event::print(FILE* file, bool short_form, char* last_db) +void Rand_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { char llbuff[22],llbuff2[22]; if (!short_form) @@ -2223,7 +2959,7 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli) { thd->rand.seed1= (ulong) seed1; thd->rand.seed2= (ulong) seed2; - rli->inc_event_relay_log_pos(get_event_len()); + rli->inc_event_relay_log_pos(); return 0; } #endif /* !MYSQL_CLIENT */ @@ -2294,10 +3030,12 @@ void User_var_log_event::pack_info(Protocol* protocol) #endif /* !MYSQL_CLIENT */ -User_var_log_event::User_var_log_event(const char* buf, bool old_format) - :Log_event(buf, old_format) +User_var_log_event:: +User_var_log_event(const char* buf, + const Format_description_log_event* description_event) + :Log_event(buf, description_event) { - buf+= (old_format) ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN; + buf+= description_event->common_header_len; name_len= uint4korr(buf); name= (char *) buf + UV_NAME_LEN_SIZE; buf+= UV_NAME_LEN_SIZE + name_len; @@ -2321,13 +3059,14 @@ User_var_log_event::User_var_log_event(const char* buf, bool old_format) } -int User_var_log_event::write_data(IO_CACHE* file) +bool User_var_log_event::write(IO_CACHE* file) { char buf[UV_NAME_LEN_SIZE]; char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE]; char buf2[8], *pos= buf2; uint buf1_length; + ulong event_length; int4store(buf, name_len); @@ -2359,7 +3098,12 @@ int User_var_log_event::write_data(IO_CACHE* file) return 0; } } - return (my_b_safe_write(file, (byte*) buf, sizeof(buf)) || + + /* Length of the whole event */ + event_length= sizeof(buf)+ name_len + buf1_length + val_len; + + return (write_header(file, event_length) || + my_b_safe_write(file, (byte*) buf, sizeof(buf)) || my_b_safe_write(file, (byte*) name, name_len) || my_b_safe_write(file, (byte*) buf1, buf1_length) || my_b_safe_write(file, (byte*) pos, val_len)); @@ -2371,7 +3115,7 @@ int User_var_log_event::write_data(IO_CACHE* file) */ #ifdef MYSQL_CLIENT -void User_var_log_event::print(FILE* file, bool short_form, char* last_db) +void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { if (!short_form) { @@ -2504,7 +3248,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) e.update_hash(val, val_len, type, charset, DERIVATION_NONE); free_root(thd->mem_root,0); - rli->inc_event_relay_log_pos(get_event_len()); + rli->inc_event_relay_log_pos(); return 0; } #endif /* !MYSQL_CLIENT */ @@ -2516,7 +3260,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) #ifdef HAVE_REPLICATION #ifdef MYSQL_CLIENT -void Unknown_log_event::print(FILE* file, bool short_form, char* last_db) +void Unknown_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { if (short_form) return; @@ -2546,7 +3290,7 @@ void Slave_log_event::pack_info(Protocol *protocol) #ifndef MYSQL_CLIENT Slave_log_event::Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli) - :Log_event(thd_arg, 0, 0), mem_pool(0), master_host(0) + :Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0) { DBUG_ENTER("Slave_log_event"); if (!rli->inited) // QQ When can this happen ? @@ -2587,7 +3331,7 @@ Slave_log_event::~Slave_log_event() #ifdef MYSQL_CLIENT -void Slave_log_event::print(FILE* file, bool short_form, char* last_db) +void Slave_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { char llbuff[22]; if (short_form) @@ -2607,12 +3351,15 @@ int Slave_log_event::get_data_size() } -int Slave_log_event::write_data(IO_CACHE* file) +bool Slave_log_event::write(IO_CACHE* file) { + ulong event_length= get_data_size(); int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos); int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port); // log and host are already there - return my_b_safe_write(file, (byte*)mem_pool, get_data_size()); + + return (write_header(file, event_length) || + my_b_safe_write(file, (byte*) mem_pool, event_length)); } @@ -2633,12 +3380,13 @@ void Slave_log_event::init_from_mem_pool(int data_size) } -Slave_log_event::Slave_log_event(const char* buf, int event_len) - :Log_event(buf,0),mem_pool(0),master_host(0) +/* This code is not used, so has not been updated to be format-tolerant */ +Slave_log_event::Slave_log_event(const char* buf, uint event_len) + :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0) { - event_len -= LOG_EVENT_HEADER_LEN; - if (event_len < 0) + if (event_len < LOG_EVENT_HEADER_LEN) return; + event_len -= LOG_EVENT_HEADER_LEN; if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME)))) return; memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len); @@ -2666,7 +3414,7 @@ int Slave_log_event::exec_event(struct st_relay_log_info* rli) */ #ifdef MYSQL_CLIENT -void Stop_log_event::print(FILE* file, bool short_form, char* last_db) +void Stop_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) { if (short_form) return; @@ -2688,7 +3436,7 @@ void Stop_log_event::print(FILE* file, bool short_form, char* last_db) We used to clean up slave_load_tmpdir, but this is useless as it has been cleared at the end of LOAD DATA INFILE. So we have nothing to do here. - The place were we must do this cleaning is in Start_log_event::exec_event(), + The place were we must do this cleaning is in Start_log_event_v3::exec_event(), not here. Because if we come here, the master was sane. */ @@ -2702,8 +3450,13 @@ int Stop_log_event::exec_event(struct st_relay_log_info* rli) could give false triggers in MASTER_POS_WAIT() that we have reached the target position when in fact we have not. */ - rli->inc_group_relay_log_pos(get_event_len(), 0); - flush_relay_log_info(rli); + if (thd->options & OPTION_BEGIN) + rli->inc_event_relay_log_pos(); + else + { + rli->inc_group_relay_log_pos(0); + flush_relay_log_info(rli); + } return 0; } #endif /* !MYSQL_CLIENT */ @@ -2740,13 +3493,13 @@ Create_file_log_event(THD* thd_arg, sql_exchange* ex, Create_file_log_event::write_data_body() */ -int Create_file_log_event::write_data_body(IO_CACHE* file) +bool Create_file_log_event::write_data_body(IO_CACHE* file) { - int res; - if ((res = Load_log_event::write_data_body(file)) || fake_base) + bool res; + if ((res= Load_log_event::write_data_body(file)) || fake_base) return res; return (my_b_safe_write(file, (byte*) "", 1) || - my_b_safe_write(file, (byte*) block, block_len)); + my_b_safe_write(file, (byte*) block, block_len)); } @@ -2754,14 +3507,14 @@ int Create_file_log_event::write_data_body(IO_CACHE* file) Create_file_log_event::write_data_header() */ -int Create_file_log_event::write_data_header(IO_CACHE* file) +bool Create_file_log_event::write_data_header(IO_CACHE* file) { - int res; - if ((res = Load_log_event::write_data_header(file)) || fake_base) - return res; + bool res; byte buf[CREATE_FILE_HEADER_LEN]; + if ((res= Load_log_event::write_data_header(file)) || fake_base) + return res; int4store(buf + CF_FILE_ID_OFFSET, file_id); - return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN); + return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0; } @@ -2769,12 +3522,12 @@ int Create_file_log_event::write_data_header(IO_CACHE* file) Create_file_log_event::write_base() */ -int Create_file_log_event::write_base(IO_CACHE* file) +bool Create_file_log_event::write_base(IO_CACHE* file) { - int res; - fake_base = 1; // pretend we are Load event - res = write(file); - fake_base = 0; + bool res; + fake_base= 1; // pretend we are Load event + res= write(file); + fake_base= 0; return res; } @@ -2783,28 +3536,43 @@ int Create_file_log_event::write_base(IO_CACHE* file) Create_file_log_event ctor */ -Create_file_log_event::Create_file_log_event(const char* buf, int len, - bool old_format) - :Load_log_event(buf,0,old_format),fake_base(0),block(0),inited_from_old(0) +Create_file_log_event::Create_file_log_event(const char* buf, uint len, + const Format_description_log_event* description_event) + :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0) { - int block_offset; - DBUG_ENTER("Create_file_log_event"); - - /* - We must make copy of 'buf' as this event may have to live over a - rotate log entry when used in mysqlbinlog - */ + DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)"); + uint block_offset; + uint header_len= description_event->common_header_len; + uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1]; + uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1]; if (!(event_buf= my_memdup((byte*) buf, len, MYF(MY_WME))) || - (copy_log_event(event_buf, len, old_format))) + copy_log_event(event_buf,len, + ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ? + load_header_len + header_len : + (fake_base ? (header_len+load_header_len) : + (header_len+load_header_len) + + create_file_header_len)), + description_event)) DBUG_VOID_RETURN; - - if (!old_format) + if (description_event->binlog_version!=1) { - file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + - + LOAD_HEADER_LEN + CF_FILE_ID_OFFSET); - // + 1 for \0 terminating fname - block_offset = (LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() + - CREATE_FILE_HEADER_LEN + 1); + file_id= uint4korr(buf + + header_len + + load_header_len + CF_FILE_ID_OFFSET); + /* + Note that it's ok to use get_data_size() below, because it is computed + with values we have already read from this event (because we called + copy_log_event()); we are not using slave's format info to decode + master's format, we are really using master's format info. + Anyway, both formats should be identical (except the common_header_len) + as these Load events are not changed between 4.0 and 5.0 (as logging of + LOAD DATA INFILE does not use Load_log_event in 5.0). + + The + 1 is for \0 terminating fname + */ + block_offset= (description_event->common_header_len + + Load_log_event::get_data_size() + + create_file_header_len + 1); if (len < block_offset) return; block = (char*)buf + block_offset; @@ -2825,18 +3593,18 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len, #ifdef MYSQL_CLIENT void Create_file_log_event::print(FILE* file, bool short_form, - char* last_db, bool enable_local) + LAST_EVENT_INFO* last_event_info, bool enable_local) { if (short_form) { if (enable_local && check_fname_outside_temp_buf()) - Load_log_event::print(file, 1, last_db); + Load_log_event::print(file, 1, last_event_info); return; } if (enable_local) { - Load_log_event::print(file, 1, last_db, !check_fname_outside_temp_buf()); + Load_log_event::print(file, 1, last_event_info, !check_fname_outside_temp_buf()); /* That one is for "file_id: etc" below: in mysqlbinlog we want the #, in SHOW BINLOG EVENTS we don't. @@ -2849,9 +3617,9 @@ void Create_file_log_event::print(FILE* file, bool short_form, void Create_file_log_event::print(FILE* file, bool short_form, - char* last_db) + LAST_EVENT_INFO* last_event_info) { - print(file,short_form,last_db,0); + print(file,short_form,last_event_info,0); } #endif /* MYSQL_CLIENT */ @@ -2968,28 +3736,34 @@ Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg, Append_block_log_event ctor */ -Append_block_log_event::Append_block_log_event(const char* buf, int len) - :Log_event(buf, 0),block(0) +Append_block_log_event::Append_block_log_event(const char* buf, uint len, + const Format_description_log_event* description_event) + :Log_event(buf, description_event),block(0) { - DBUG_ENTER("Append_block_log_event"); - if ((uint)len < APPEND_BLOCK_EVENT_OVERHEAD) + DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)"); + uint8 common_header_len= description_event->common_header_len; + uint8 append_block_header_len= + description_event->post_header_len[APPEND_BLOCK_EVENT-1]; + uint total_header_len= common_header_len+append_block_header_len; + if (len < total_header_len) DBUG_VOID_RETURN; - file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET); - block = (char*)buf + APPEND_BLOCK_EVENT_OVERHEAD; - block_len = len - APPEND_BLOCK_EVENT_OVERHEAD; + file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET); + block= (char*)buf + total_header_len; + block_len= len - total_header_len; DBUG_VOID_RETURN; } /* - Append_block_log_event::write_data() + Append_block_log_event::write() */ -int Append_block_log_event::write_data(IO_CACHE* file) +bool Append_block_log_event::write(IO_CACHE* file) { byte buf[APPEND_BLOCK_HEADER_LEN]; int4store(buf + AB_FILE_ID_OFFSET, file_id); - return (my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) || + return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) || + my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) || my_b_safe_write(file, (byte*) block, block_len)); } @@ -3000,7 +3774,7 @@ int Append_block_log_event::write_data(IO_CACHE* file) #ifdef MYSQL_CLIENT void Append_block_log_event::print(FILE* file, bool short_form, - char* last_db) + LAST_EVENT_INFO* last_event_info) { if (short_form) return; @@ -3086,24 +3860,28 @@ Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg, Delete_file_log_event ctor */ -Delete_file_log_event::Delete_file_log_event(const char* buf, int len) - :Log_event(buf, 0),file_id(0) +Delete_file_log_event::Delete_file_log_event(const char* buf, uint len, + const Format_description_log_event* description_event) + :Log_event(buf, description_event),file_id(0) { - if ((uint)len < DELETE_FILE_EVENT_OVERHEAD) + uint8 common_header_len= description_event->common_header_len; + uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1]; + if (len < (uint)(common_header_len + delete_file_header_len)) return; - file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + AB_FILE_ID_OFFSET); + file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET); } /* - Delete_file_log_event::write_data() + Delete_file_log_event::write() */ -int Delete_file_log_event::write_data(IO_CACHE* file) +bool Delete_file_log_event::write(IO_CACHE* file) { byte buf[DELETE_FILE_HEADER_LEN]; int4store(buf + DF_FILE_ID_OFFSET, file_id); - return my_b_safe_write(file, buf, DELETE_FILE_HEADER_LEN); + return (write_header(file, sizeof(buf)) || + my_b_safe_write(file, buf, sizeof(buf))); } @@ -3113,7 +3891,7 @@ int Delete_file_log_event::write_data(IO_CACHE* file) #ifdef MYSQL_CLIENT void Delete_file_log_event::print(FILE* file, bool short_form, - char* last_db) + LAST_EVENT_INFO* last_event_info) { if (short_form) return; @@ -3176,24 +3954,28 @@ Execute_load_log_event::Execute_load_log_event(THD *thd_arg, const char* db_arg, Execute_load_log_event ctor */ -Execute_load_log_event::Execute_load_log_event(const char* buf, int len) - :Log_event(buf, 0), file_id(0) +Execute_load_log_event::Execute_load_log_event(const char* buf, uint len, + const Format_description_log_event* description_event) + :Log_event(buf, description_event), file_id(0) { - if ((uint)len < EXEC_LOAD_EVENT_OVERHEAD) + uint8 common_header_len= description_event->common_header_len; + uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1]; + if (len < (uint)(common_header_len+exec_load_header_len)) return; - file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN + EL_FILE_ID_OFFSET); + file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET); } /* - Execute_load_log_event::write_data() + Execute_load_log_event::write() */ -int Execute_load_log_event::write_data(IO_CACHE* file) +bool Execute_load_log_event::write(IO_CACHE* file) { byte buf[EXEC_LOAD_HEADER_LEN]; int4store(buf + EL_FILE_ID_OFFSET, file_id); - return my_b_safe_write(file, buf, EXEC_LOAD_HEADER_LEN); + return (write_header(file, sizeof(buf)) || + my_b_safe_write(file, buf, sizeof(buf))); } @@ -3203,7 +3985,7 @@ int Execute_load_log_event::write_data(IO_CACHE* file) #ifdef MYSQL_CLIENT void Execute_load_log_event::print(FILE* file, bool short_form, - char* last_db) + LAST_EVENT_INFO* last_event_info) { if (short_form) return; @@ -3250,8 +4032,8 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) goto err; } if (!(lev = (Load_log_event*)Log_event::read_log_event(&file, - (pthread_mutex_t*)0, - (bool)0)) || + (pthread_mutex_t*)0, + rli->relay_log.description_event_for_exec)) || lev->get_type_code() != NEW_LOAD_EVENT) { slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname); @@ -3266,15 +4048,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) mysql_load()). */ -#if MYSQL_VERSION_ID < 40100 - rli->future_master_log_pos= log_pos + get_event_len() - - (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); -#elif MYSQL_VERSION_ID < 50000 - rli->future_group_master_log_pos= log_pos + get_event_len() - - (rli->mi->old_format ? (LOG_EVENT_HEADER_LEN - OLD_HEADER_LEN) : 0); -#else - rli->future_group_master_log_pos= log_pos; -#endif + rli->future_group_master_log_pos= log_pos; if (lev->exec_event(0,rli,1)) { /* @@ -3332,15 +4106,15 @@ err: sql_ex_info::write_data() */ -int sql_ex_info::write_data(IO_CACHE* file) +bool sql_ex_info::write_data(IO_CACHE* file) { if (new_format()) { - return (write_str(file, field_term, field_term_len) || - write_str(file, enclosed, enclosed_len) || - write_str(file, line_term, line_term_len) || - write_str(file, line_start, line_start_len) || - write_str(file, escaped, escaped_len) || + return (write_str(file, field_term, (uint) field_term_len) || + write_str(file, enclosed, (uint) enclosed_len) || + write_str(file, line_term, (uint) line_term_len) || + write_str(file, line_start, (uint) line_start_len) || + write_str(file, escaped, (uint) escaped_len) || my_b_safe_write(file,(byte*) &opt_flags,1)); } else @@ -3353,7 +4127,7 @@ int sql_ex_info::write_data(IO_CACHE* file) old_ex.escaped= *escaped; old_ex.opt_flags= opt_flags; old_ex.empty_flags=empty_flags; - return my_b_safe_write(file, (byte*) &old_ex, sizeof(old_ex)); + return my_b_safe_write(file, (byte*) &old_ex, sizeof(old_ex)) != 0; } } @@ -3375,11 +4149,11 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format) the case when we have old format because we will be reusing net buffer to read the actual file before we write out the Create_file event. */ - if (read_str(buf, buf_end, field_term, field_term_len) || - read_str(buf, buf_end, enclosed, enclosed_len) || - read_str(buf, buf_end, line_term, line_term_len) || - read_str(buf, buf_end, line_start, line_start_len) || - read_str(buf, buf_end, escaped, escaped_len)) + if (read_str(&buf, buf_end, &field_term, &field_term_len) || + read_str(&buf, buf_end, &enclosed, &enclosed_len) || + read_str(&buf, buf_end, &line_term, &line_term_len) || + read_str(&buf, buf_end, &line_start, &line_start_len) || + read_str(&buf, buf_end, &escaped, &escaped_len)) return 0; opt_flags = *buf++; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9d755731cb7..5e9162b52b2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -26,6 +26,9 @@ #include "ha_innodb.h" #endif +#include "sp_head.h" +#include "sp.h" + #ifdef HAVE_OPENSSL /* Without SSL the handshake consists of one packet. This packet @@ -44,6 +47,15 @@ #define MIN_HANDSHAKE_SIZE 6 #endif /* HAVE_OPENSSL */ +/* Used in error handling only */ +#define SP_TYPE_STRING(LP) \ + ((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE") +#define SP_COM_STRING(LP) \ + ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \ + (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \ + (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \ + "FUNCTION" : "PROCEDURE") + #ifdef SOLARIS extern "C" int gethostname(char *name, int namelen); #endif @@ -57,6 +69,7 @@ static void remove_escape(char *name); static void refresh_status(void); static bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); +static bool check_sp_definer_access(THD *thd, sp_head *sp); const char *any_db="*any*"; // Special symbol for check_access @@ -66,7 +79,7 @@ const char *command_name[]={ "Connect","Kill","Debug","Ping","Time","Delayed insert","Change user", "Binlog Dump","Table Dump", "Connect Out", "Register Slave", "Prepare", "Prepare Execute", "Long Data", "Close stmt", - "Reset stmt", "Set option", + "Reset stmt", "Set option", "Fetch", "Error" // Last command number }; @@ -96,7 +109,7 @@ static void unlock_locked_tables(THD *thd) if (thd->locked_tables) { thd->lock=thd->locked_tables; - thd->locked_tables=0; // Will be automaticly closed + thd->locked_tables=0; // Will be automatically closed close_thread_tables(thd); // Free tables } } @@ -193,13 +206,13 @@ end: command originator of the check: now check_user is called during connect and change user procedures; used for logging. - passwd scrambled password recieved from client + passwd scrambled password received from client passwd_len length of scrambled password db database name to connect to, may be NULL check_count dont know exactly Note, that host, user and passwd may point to communication buffer. - Current implementation does not depened on that, but future changes + Current implementation does not depend on that, but future changes should be done with this in mind; 'thd' is INOUT, all other params are 'IN'. @@ -257,7 +270,7 @@ int check_user(THD *thd, enum enum_server_command command, /* Clear thd->db as it points to something, that will be freed when - connection is closed. We don't want to accidently free a wrong pointer + connection is closed. We don't want to accidentally free a wrong pointer if connect failed. Also in case of 'CHANGE USER' failure, current database will be switched to 'no database selected'. */ @@ -284,9 +297,10 @@ int check_user(THD *thd, enum enum_server_command command, thd->user, thd->host_or_ip); DBUG_RETURN(-1); } + /* We have to read very specific packet size */ if (send_old_password_request(thd) || - my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) // We have to read very - { // specific packet size + my_net_read(net) != SCRAMBLE_LENGTH_323 + 1) + { inc_host_errors(&thd->remote.sin_addr); DBUG_RETURN(ER_HANDSHAKE_ERROR); } @@ -298,7 +312,7 @@ int check_user(THD *thd, enum enum_server_command command, /* here res is always >= 0 */ if (res == 0) { - if (!(thd->master_access & NO_ACCESS)) // authentification is OK + if (!(thd->master_access & NO_ACCESS)) // authentication is OK { DBUG_PRINT("info", ("Capabilities: %d packet_length: %ld Host: '%s' " @@ -533,6 +547,8 @@ void init_update_queries(void) uc_update_queries[SQLCOM_DELETE_MULTI]=1; uc_update_queries[SQLCOM_DROP_INDEX]=1; uc_update_queries[SQLCOM_UPDATE_MULTI]=1; + uc_update_queries[SQLCOM_CREATE_VIEW]=1; + uc_update_queries[SQLCOM_DROP_VIEW]=1; } bool is_update_query(enum enum_sql_command command) @@ -621,8 +637,9 @@ static void reset_mqh(THD *thd, LEX_USER *lu, bool get_them= 0) uc->conn_per_hour=0; } } - else // for FLUSH PRIVILEGES and FLUSH USER_RESOURCES + else { + /* for FLUSH PRIVILEGES and FLUSH USER_RESOURCES */ for (uint idx=0;idx < hash_user_connections.records; idx++) { USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections, @@ -721,7 +738,7 @@ static int check_connection(THD *thd) #endif /* HAVE_COMPRESS */ #ifdef HAVE_OPENSSL if (ssl_acceptor_fd) - client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */ + client_flags |= CLIENT_SSL; /* Wow, SSL is available! */ #endif /* HAVE_OPENSSL */ end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1; @@ -948,7 +965,7 @@ pthread_handler_decl(handle_one_connection,arg) pthread_detach_this_thread(); #if !defined( __WIN__) && !defined(OS2) // Win32 calls this in pthread_create - // The following calls needs to be done before we call DBUG_ macros + /* The following calls needs to be done before we call DBUG_ macros */ if (!(test_flags & TEST_NO_THREADS) & my_thread_init()) { close_connection(thd, ER_OUT_OF_RESOURCES, 1); @@ -967,7 +984,7 @@ pthread_handler_decl(handle_one_connection,arg) */ DBUG_PRINT("info", ("handle_one_connection called by thread %d\n", thd->thread_id)); - // now that we've called my_thread_init(), it is safe to call DBUG_* + /* now that we've called my_thread_init(), it is safe to call DBUG_* */ #if defined(__WIN__) init_signals(); // IRENA; testing ? @@ -1013,24 +1030,28 @@ pthread_handler_decl(handle_one_connection,arg) thd->proc_info= 0; thd->set_time(); thd->init_for_queries(); + if (sys_init_connect.value_length && !(thd->master_access & SUPER_ACL)) { execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect); if (thd->query_error) - thd->killed= 1; + thd->killed= THD::KILL_CONNECTION; } - while (!net->error && net->vio != 0 && !thd->killed) + + thd->proc_info=0; + thd->set_time(); + thd->init_for_queries(); + while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION)) { if (do_command(thd)) break; } if (thd->user_connect) decrease_user_connections(thd->user_connect); - free_root(thd->mem_root,MYF(0)); if (net->error && net->vio != 0 && net->report_error) { if (!thd->killed && thd->variables.log_warnings > 1) - sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), thd->thread_id,(thd->db ? thd->db : "unconnected"), thd->user ? thd->user : "unauthenticated", thd->host_or_ip, @@ -1116,6 +1137,10 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) thd->query_length=length; thd->query= thd->memdup_w_gap(buff, length+1, thd->db_length+1); thd->query[length] = '\0'; + /* + We don't need to obtain LOCK_thread_count here because in bootstrap + mode we have only one thread. + */ thd->query_id=query_id++; if (mqh_used && thd->user_connect && check_mqh(thd, SQLCOM_END)) { @@ -1149,8 +1174,10 @@ end: void free_items(Item *item) { + DBUG_ENTER("free_items"); for (; item ; item=item->next) item->delete_self(); + DBUG_VOID_RETURN; } /* This works because items are allocated with sql_alloc() */ @@ -1170,10 +1197,10 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) db = (db && db[0]) ? db : thd->db; if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST)))) DBUG_RETURN(1); // out of memory - table_list->db = db; - table_list->real_name = table_list->alias = tbl_name; - table_list->lock_type = TL_READ_NO_INSERT; - table_list->next = 0; + table_list->db= db; + table_list->real_name= table_list->alias= tbl_name; + table_list->lock_type= TL_READ_NO_INSERT; + table_list->prev_global= &table_list; // can be removed after merge with 4.1 if (!db || check_db_name(db)) { @@ -1237,7 +1264,7 @@ bool do_command(THD *thd) packet=0; old_timeout=net->read_timeout; - // Wait max for 8 hours + /* Wait max for 8 hours */ net->read_timeout=(uint) thd->variables.net_wait_timeout; thd->clear_error(); // Clear error message @@ -1259,6 +1286,9 @@ bool do_command(THD *thd) } else { + if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA) + thd->killed= THD::NOT_KILLED; + packet=(char*) net->read_pos; command = (enum enum_server_command) (uchar) packet[0]; if (command >= COM_END) @@ -1310,6 +1340,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, this so that they will not get logged to the slow query log */ thd->slow_command=FALSE; + thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ thd->set_time(); VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id=query_id; @@ -1325,7 +1356,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_INIT_DB: { LEX_STRING tmp; - statistic_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB], + &LOCK_status); thd->convert_string(&tmp, system_charset_info, packet, strlen(packet), thd->charset()); if (!mysql_change_db(thd, tmp.str)) @@ -1346,7 +1378,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, uint db_len= *(uchar*) packet; uint tbl_len= *(uchar*) (packet + db_len + 1); - statistic_increment(com_other, &LOCK_status); + statistic_increment(thd->status_var.com_other, &LOCK_status); thd->slow_command= TRUE; db= thd->alloc(db_len + tbl_len + 2); tbl_name= strmake(db, packet + 1, db_len)+1; @@ -1360,7 +1392,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->change_user(); thd->clear_error(); // if errors from rollback - statistic_increment(com_other, &LOCK_status); + statistic_increment(thd->status_var.com_other, &LOCK_status); char *user= (char*) packet; char *passwd= strend(user)+1; /* @@ -1374,7 +1406,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, *passwd++ : strlen(passwd); db+= passwd_len + 1; #ifndef EMBEDDED_LIBRARY - /* Small check for incomming packet */ + /* Small check for incoming packet */ if ((uint) ((uchar*) db - net->read_pos) > packet_length) { send_error(thd, ER_UNKNOWN_COM_ERROR); @@ -1410,7 +1442,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (res) { - /* authentification failure, we shall restore old user */ + /* authentication failure, we shall restore old user */ if (res > 0) send_error(thd, ER_UNKNOWN_COM_ERROR); x_free(thd->user); @@ -1437,6 +1469,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, mysql_stmt_execute(thd, packet, packet_length); break; } + case COM_FETCH: + { + mysql_stmt_fetch(thd, packet, packet_length); + break; + } case COM_LONG_DATA: { mysql_stmt_get_longdata(thd, packet, packet_length); @@ -1523,20 +1560,20 @@ bool dispatch_command(enum enum_server_command command, THD *thd, TABLE_LIST table_list; LEX_STRING conv_name; - statistic_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS], + &LOCK_status); bzero((char*) &table_list,sizeof(table_list)); if (!(table_list.db=thd->db)) { send_error(thd,ER_NO_DB_ERROR); break; } - thd->free_list=0; pend= strend(packet); thd->convert_string(&conv_name, system_charset_info, packet, (uint) (pend-packet), thd->charset()); table_list.alias= table_list.real_name= conv_name.str; packet= pend+1; - // command not cachable => no gap for data base name + /* command not cachable => no gap for data base name */ if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1))) break; mysql_log.write(thd,command,"%s %s",table_list.real_name,fields); @@ -1550,9 +1587,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (grant_option && check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0)) break; + /* init structures for VIEW processing */ + table_list.select_lex= &(thd->lex->select_lex); + mysql_init_query(thd, (uchar*)"", 0); + thd->lex-> + select_lex.table_list.link_in_list((byte*) &table_list, + (byte**) &table_list.next_local); + + /* switch on VIEW optimisation: do not fill temporary tables */ + thd->lex->sql_command= SQLCOM_SHOW_FIELDS; mysqld_list_fields(thd,&table_list,fields); - free_items(thd->free_list); - thd->free_list= 0; + thd->lex->unit.cleanup(); + thd->cleanup_after_query(); break; } #endif @@ -1568,7 +1614,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char *db=thd->strdup(packet), *alias; HA_CREATE_INFO create_info; - statistic_increment(com_stat[SQLCOM_CREATE_DB],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB], + &LOCK_status); // null test to handle EOM if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { @@ -1586,9 +1633,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_DROP_DB: // QQ: To be removed { - statistic_increment(com_stat[SQLCOM_DROP_DB],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_DROP_DB], + &LOCK_status); char *db=thd->strdup(packet), *alias; - // null test to handle EOM + /* null test to handle EOM */ if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { net_printf(thd,ER_WRONG_DB_NAME, db ? db : "NULL"); @@ -1614,7 +1662,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ushort flags; uint32 slave_server_id; - statistic_increment(com_other,&LOCK_status); + statistic_increment(thd->status_var.com_other,&LOCK_status); thd->slow_command = TRUE; if (check_global_access(thd, REPL_SLAVE_ACL)) break; @@ -1631,7 +1679,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, (long) pos); mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags); unregister_slave(thd,1,1); - // fake COM_QUIT -- if we get here, the thread needs to terminate + /* fake COM_QUIT -- if we get here, the thread needs to terminate */ error = TRUE; net->error = 0; break; @@ -1639,7 +1687,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif case COM_REFRESH: { - statistic_increment(com_stat[SQLCOM_FLUSH],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_FLUSH], + &LOCK_status); ulong options= (ulong) (uchar) packet[0]; if (check_global_access(thd,RELOAD_ACL)) break; @@ -1653,7 +1702,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #ifndef EMBEDDED_LIBRARY case COM_SHUTDOWN: { - statistic_increment(com_other,&LOCK_status); + statistic_increment(thd->status_var.com_other, &LOCK_status); if (check_global_access(thd,SHUTDOWN_ACL)) break; /* purecov: inspected */ /* @@ -1684,8 +1733,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, #endif close_connection(thd, 0, 1); close_thread_tables(thd); // Free before kill - free_root(thd->mem_root,MYF(0)); - free_root(&thd->transaction.mem_root,MYF(0)); kill_mysql(); error=TRUE; break; @@ -1694,7 +1741,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_STATISTICS: { mysql_log.write(thd,command,NullS); - statistic_increment(com_stat[SQLCOM_SHOW_STATUS],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS], + &LOCK_status); #ifndef EMBEDDED_LIBRARY char buff[200]; #else @@ -1704,8 +1752,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, sprintf((char*) buff, "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %u Queries per second avg: %.3f", uptime, - (int) thread_count,thd->query_id,long_query_count, - opened_tables,refresh_version, cached_tables(), + (int) thread_count,thd->query_id,thd->status_var.long_query_count, + thd->status_var.opened_tables,refresh_version, cached_tables(), uptime ? (float)thd->query_id/(float)uptime : 0); #ifdef SAFEMALLOC if (sf_malloc_cur_memory) // Using SAFEMALLOC @@ -1720,11 +1768,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } case COM_PING: - statistic_increment(com_other,&LOCK_status); + statistic_increment(thd->status_var.com_other, &LOCK_status); send_ok(thd); // Tell client we are alive break; case COM_PROCESS_INFO: - statistic_increment(com_stat[SQLCOM_SHOW_PROCESSLIST],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST], + &LOCK_status); if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) break; mysql_log.write(thd,command,NullS); @@ -1734,14 +1783,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; case COM_PROCESS_KILL: { - statistic_increment(com_stat[SQLCOM_KILL],&LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_KILL], &LOCK_status); ulong id=(ulong) uint4korr(packet); - kill_one_thread(thd,id); + kill_one_thread(thd,id,false); break; } case COM_SET_OPTION: { - statistic_increment(com_stat[SQLCOM_SET_OPTION], &LOCK_status); + statistic_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION], + &LOCK_status); enum_mysql_set_option command= (enum_mysql_set_option) uint2korr(packet); switch (command) { case MYSQL_OPTION_MULTI_STATEMENTS_ON: @@ -1759,7 +1809,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } case COM_DEBUG: - statistic_increment(com_other,&LOCK_status); + statistic_increment(thd->status_var.com_other, &LOCK_status); if (check_global_access(thd, SUPER_ACL)) break; /* purecov: inspected */ mysql_print_status(thd); @@ -1798,7 +1848,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && (specialflag & SPECIAL_LOG_QUERIES_NOT_USING_INDEXES))) { - long_query_count++; + thd->status_var.long_query_count++; mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query); } } @@ -1811,6 +1861,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory + free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); DBUG_RETURN(error); } @@ -1870,23 +1921,54 @@ bool alloc_query(THD *thd, char *packet, ulong packet_length) ** Execute command saved in thd and current_lex->sql_command ****************************************************************************/ -void +int mysql_execute_command(THD *thd) { int res= 0; LEX *lex= thd->lex; + /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ SELECT_LEX *select_lex= &lex->select_lex; - TABLE_LIST *tables= (TABLE_LIST*) select_lex->table_list.first; + /* first table of first SELECT_LEX */ + TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first; + /* list of all tables in query */ + TABLE_LIST *all_tables; + /* most outer SELECT_LEX_UNIT of query */ SELECT_LEX_UNIT *unit= &lex->unit; DBUG_ENTER("mysql_execute_command"); + /* + In many cases first table of main SELECT_LEX have special meaning => + check that it is first table in global list and relink it first in + queries_tables list if it is necessary (we need such relinking only + for queries with subqueries in select list, in this case tables of + subqueries will go to global list first) + + all_tables will differ from first_table only if most upper SELECT_LEX + do not contain tables. + + Because of above in place where should be at least one table in most + outer SELECT_LEX we have following check: + DBUG_ASSERT(first_table == all_tables); + DBUG_ASSERT(first_table == all_tables && first_table != 0); + */ + lex->first_lists_tables_same(); + /* should be assigned after making first tables same */ + all_tables= lex->query_tables; + + if (lex->sql_command != SQLCOM_CREATE_PROCEDURE && + lex->sql_command != SQLCOM_CREATE_SPFUNCTION) + { + if (sp_cache_functions(thd, lex)) + DBUG_RETURN(-1); + } + /* Reset warning count for each query that uses tables A better approach would be to reset this for any commands that is not a SHOW command or a select that only access local variables, but for now this is probably good enough. */ - if (tables || &lex->select_lex != lex->all_selects_list) + if (all_tables || &lex->select_lex != lex->all_selects_list) mysql_reset_errors(thd); #ifdef HAVE_REPLICATION @@ -1896,11 +1978,11 @@ mysql_execute_command(THD *thd) Skip if we are in the slave thread, some table rules have been given and the table list says the query should not be replicated */ - if (all_tables_not_ok(thd,tables)) + if (all_tables_not_ok(thd, all_tables)) { /* we warn the slave SQL thread */ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); - DBUG_VOID_RETURN; + DBUG_RETURN(0); } #ifndef TO_BE_DELETED /* @@ -1916,10 +1998,20 @@ mysql_execute_command(THD *thd) #endif } #endif /* !HAVE_REPLICATION */ - if ((&lex->select_lex != lex->all_selects_list || - lex->time_zone_tables_used) && - lex->unit.create_total_list(thd, lex, &tables)) - DBUG_VOID_RETURN; + + if (lex->time_zone_tables_used) + { + TABLE_LIST *tmp; + if ((tmp= my_tz_get_table_list(thd, &lex->query_tables_last)) == + &fake_time_zone_tables_list) + { + send_error(thd, 0); + DBUG_RETURN(-1); + } + lex->time_zone_tables_used= tmp; + if (!all_tables) + all_tables= tmp; + } /* When option readonly is set deny operations which change tables. @@ -1930,10 +2022,11 @@ mysql_execute_command(THD *thd) (uc_update_queries[lex->sql_command] > 0)) { net_printf(thd, ER_OPTION_PREVENTS_STATEMENT, "--read-only"); - DBUG_VOID_RETURN; + DBUG_RETURN(-1); } - statistic_increment(com_stat[lex->sql_command],&LOCK_status); + statistic_increment(thd->status_var.com_stat[lex->sql_command], + &LOCK_status); switch (lex->sql_command) { case SQLCOM_SELECT: { @@ -1945,42 +2038,31 @@ mysql_execute_command(THD *thd) } select_result *result=lex->result; - if (tables) + if (all_tables) { - res=check_table_access(thd, - lex->exchange ? SELECT_ACL | FILE_ACL : - SELECT_ACL, - tables,0); + res= check_table_access(thd, + lex->exchange ? SELECT_ACL | FILE_ACL : + SELECT_ACL, + all_tables, 0); } else - res=check_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, - any_db,0,0,0); + res= check_access(thd, + lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, + any_db, 0, 0, 0); if (res) { res=0; break; // Error message is given } - /* - In case of single SELECT unit->global_parameters points on first SELECT - TODO: move counters to SELECT_LEX - */ - unit->offset_limit_cnt= (ha_rows) unit->global_parameters->offset_limit; - unit->select_limit_cnt= (ha_rows) (unit->global_parameters->select_limit+ - unit->global_parameters->offset_limit); - if (unit->select_limit_cnt < - (ha_rows) unit->global_parameters->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // no limit - if (unit->select_limit_cnt == HA_POS_ERROR && !select_lex->next_select()) - select_lex->options&= ~OPTION_FOUND_ROWS; - if (!(res=open_and_lock_tables(thd,tables))) + if (!(res= open_and_lock_tables(thd, all_tables))) { if (lex->describe) { if (!(result= new select_send())) { send_error(thd, ER_OUT_OF_RESOURCES); - DBUG_VOID_RETURN; + goto error; } else thd->send_explain_fields(result); @@ -2005,7 +2087,7 @@ mysql_execute_command(THD *thd) res= -1; break; } - query_cache_store_query(thd, tables); + query_cache_store_query(thd, all_tables); res= handle_select(thd, lex, result); if (result != lex->result) delete result; @@ -2127,8 +2209,9 @@ mysql_execute_command(THD *thd) break; } case SQLCOM_DO: - if (tables && ((res= check_table_access(thd, SELECT_ACL, tables,0)) || - (res= open_and_lock_tables(thd,tables)))) + if (all_tables && + ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || + (res= open_and_lock_tables(thd, all_tables)))) break; res= mysql_do(thd, *lex->insert_list); @@ -2149,7 +2232,7 @@ mysql_execute_command(THD *thd) { if (check_global_access(thd, SUPER_ACL)) goto error; - // PURGE MASTER LOGS TO 'file' + /* PURGE MASTER LOGS TO 'file' */ res = purge_master_logs(thd, lex->to_log); break; } @@ -2157,7 +2240,7 @@ mysql_execute_command(THD *thd) { if (check_global_access(thd, SUPER_ACL)) goto error; - // PURGE MASTER LOGS BEFORE 'data' + /* PURGE MASTER LOGS BEFORE 'data' */ res = purge_master_logs_before_date(thd, lex->purge_time); break; } @@ -2210,41 +2293,45 @@ mysql_execute_command(THD *thd) case SQLCOM_BACKUP_TABLE: { - if (check_db_used(thd,tables) || - check_table_access(thd,SELECT_ACL, tables,0) || + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, SELECT_ACL, all_tables, 0) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; - res = mysql_backup_table(thd, tables); + res = mysql_backup_table(thd, first_table); break; } case SQLCOM_RESTORE_TABLE: { - if (check_db_used(thd,tables) || - check_table_access(thd, INSERT_ACL, tables,0) || + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, INSERT_ACL, all_tables, 0) || check_global_access(thd, FILE_ACL)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; - res = mysql_restore_table(thd, tables); + res = mysql_restore_table(thd, first_table); break; } case SQLCOM_ASSIGN_TO_KEYCACHE: { - if (check_db_used(thd, tables) || - check_access(thd, INDEX_ACL, tables->db, - &tables->grant.privilege, 0, 0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_access(thd, INDEX_ACL, first_table->db, + &first_table->grant.privilege, 0, 0)) goto error; - res= mysql_assign_to_keycache(thd, tables, &lex->name_and_length); + res= mysql_assign_to_keycache(thd, first_table, &lex->name_and_length); break; } case SQLCOM_PRELOAD_KEYS: { - if (check_db_used(thd, tables) || - check_access(thd, INDEX_ACL, tables->db, - &tables->grant.privilege, 0, 0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_access(thd, INDEX_ACL, first_table->db, + &first_table->grant.privilege, 0, 0)) goto error; - res = mysql_preload_keys(thd, tables); + res = mysql_preload_keys(thd, first_table); break; } #ifdef HAVE_REPLICATION @@ -2297,19 +2384,21 @@ mysql_execute_command(THD *thd) #ifdef HAVE_REPLICATION case SQLCOM_LOAD_MASTER_TABLE: { - if (!tables->db) - tables->db=thd->db; - if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege,0,0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (!first_table->db) + first_table->db= thd->db; + if (check_access(thd, CREATE_ACL, first_table->db, + &first_table->grant.privilege, 0, 0)) goto error; /* purecov: inspected */ if (grant_option) { /* Check that the first table has CREATE privilege */ - if (check_grant(thd, CREATE_ACL, tables, 0, 1, 0)) + if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0)) goto error; } - if (strlen(tables->real_name) > NAME_LEN) + if (strlen(first_table->real_name) > NAME_LEN) { - net_printf(thd,ER_WRONG_TABLE_NAME, tables->real_name); + net_printf(thd, ER_WRONG_TABLE_NAME, first_table->real_name); break; } pthread_mutex_lock(&LOCK_active_mi); @@ -2317,7 +2406,7 @@ mysql_execute_command(THD *thd) fetch_master_table will send the error to the client on failure. Give error if the table already exists. */ - if (!fetch_master_table(thd, tables->db, tables->real_name, + if (!fetch_master_table(thd, first_table->db, first_table->real_name, active_mi, 0, 0)) { send_ok(thd); @@ -2329,12 +2418,13 @@ mysql_execute_command(THD *thd) case SQLCOM_CREATE_TABLE: { - /* Skip first table, which is the table we are creating */ - TABLE_LIST *create_table, *create_table_local; - tables= lex->unlink_first_table(tables, &create_table, - &create_table_local); + DBUG_ASSERT(first_table == all_tables && first_table != 0); + bool link_to_local; + // Skip first table, which is the table we are creating + TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local); + TABLE_LIST *select_tables= lex->query_tables; - if ((res= create_table_precheck(thd, tables, create_table))) + if ((res= create_table_precheck(thd, select_tables, create_table))) goto unsent_create_error; #ifndef HAVE_READLINK @@ -2343,7 +2433,7 @@ mysql_execute_command(THD *thd) /* Fix names if symlinked tables */ if (append_file_to_dir(thd, &lex->create_info.data_file_name, create_table->real_name) || - append_file_to_dir(thd,&lex->create_info.index_file_name, + append_file_to_dir(thd, &lex->create_info.index_file_name, create_table->real_name)) { res=-1; @@ -2351,7 +2441,7 @@ mysql_execute_command(THD *thd) } #endif /* - If we are using SET CHARSET without DEFAULT, add an implicite + If we are using SET CHARSET without DEFAULT, add an implicit DEFAULT to not confuse old users. (This may change). */ if ((lex->create_info.used_fields & @@ -2368,21 +2458,42 @@ mysql_execute_command(THD *thd) select_result *result; select_lex->options|= SELECT_NO_UNLOCK; - unit->offset_limit_cnt= select_lex->offset_limit; - unit->select_limit_cnt= select_lex->select_limit+ - select_lex->offset_limit; - if (unit->select_limit_cnt < select_lex->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // No limit + unit->set_limit(select_lex, select_lex); - if (!(res=open_and_lock_tables(thd,tables))) + if (!(res= open_and_lock_tables(thd, select_tables))) { - res= -1; // If error - if ((result=new select_create(create_table->db, - create_table->real_name, - &lex->create_info, - lex->create_list, - lex->key_list, - select_lex->item_list,lex->duplicates))) + /* + Is table which we are changing used somewhere in other parts + of query + */ + if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && + unique_table(create_table, select_tables)) + { + net_printf(thd, ER_UPDATE_TABLE_USED, create_table->real_name); + goto create_error; + } + /* If we create merge table, we have to test tables in merge, too */ + if (lex->create_info.used_fields & HA_CREATE_USED_UNION) + { + TABLE_LIST *tab; + for (tab= (TABLE_LIST*) lex->create_info.merge_list.first; + tab; + tab= tab->next_local) + { + if (unique_table(tab, select_tables)) + { + net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); + goto create_error; + } + } + } + + if ((result= new select_create(create_table, + &lex->create_info, + lex->create_list, + lex->key_list, + select_lex->item_list, + lex->duplicates))) { /* CREATE from SELECT give its SELECT_LEX for SELECT, @@ -2391,49 +2502,48 @@ mysql_execute_command(THD *thd) select_lex->resolve_mode= SELECT_LEX::SELECT_MODE; res=handle_select(thd, lex, result); select_lex->resolve_mode= SELECT_LEX::NOMATTER_MODE; + delete result; } - //reset for PS + /* reset for PS */ lex->create_list.empty(); lex->key_list.empty(); } } - else // regular create + else { + /* regular create */ if (lex->name) res= mysql_create_like_table(thd, create_table, &lex->create_info, (Table_ident *)lex->name); else { - res= mysql_create_table(thd,create_table->db, - create_table->real_name, &lex->create_info, - lex->create_list, - lex->key_list,0,0); + res= mysql_create_table(thd, create_table->db, + create_table->real_name, &lex->create_info, + lex->create_list, + lex->key_list, 0, 0); } if (!res) send_ok(thd); } - - // put tables back for PS rexecuting - tables= lex->link_first_table_back(tables, create_table, - create_table_local); + lex->link_first_table_back(create_table, link_to_local); break; create_error: - res= 1; //error reported + res= 1; //error reported unsent_create_error: - // put tables back for PS rexecuting - tables= lex->link_first_table_back(tables, create_table, - create_table_local); + /* put tables back for PS rexecuting */ + lex->link_first_table_back(create_table, link_to_local); break; } case SQLCOM_CREATE_INDEX: - if (check_one_table_access(thd, INDEX_ACL, tables)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_one_table_access(thd, INDEX_ACL, all_tables)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; if (end_active_trans(thd)) res= -1; else - res = mysql_create_index(thd, tables, lex->key_list); + res = mysql_create_index(thd, first_table, lex->key_list); break; #ifdef HAVE_REPLICATION @@ -2461,7 +2571,7 @@ unsent_create_error: if (thd->locked_tables || thd->active_transaction()) { send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION); - break; + goto error; } { pthread_mutex_lock(&LOCK_active_mi); @@ -2472,9 +2582,10 @@ unsent_create_error: #endif /* HAVE_REPLICATION */ case SQLCOM_ALTER_TABLE: + DBUG_ASSERT(first_table == all_tables && first_table != 0); #if defined(DONT_ALLOW_SHOW_COMMANDS) send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - break; + goto error; #else { ulong priv=0; @@ -2485,16 +2596,17 @@ unsent_create_error: break; } if (!select_lex->db) - select_lex->db=tables->db; - if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege,0,0) || + select_lex->db= first_table->db; + if (check_access(thd, ALTER_ACL, first_table->db, + &first_table->grant.privilege, 0, 0) || check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0)|| - check_merge_table_access(thd, tables->db, + check_merge_table_access(thd, first_table->db, (TABLE_LIST *) lex->create_info.merge_list.first)) goto error; /* purecov: inspected */ if (grant_option) { - if (check_grant(thd, ALTER_ACL, tables, 0, UINT_MAX, 0)) + if (check_grant(thd, ALTER_ACL, all_tables, 0, UINT_MAX, 0)) goto error; if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL)) { // Rename of table @@ -2518,7 +2630,7 @@ unsent_create_error: thd->slow_command=TRUE; res= mysql_alter_table(thd, select_lex->db, lex->name, &lex->create_info, - tables, lex->create_list, + first_table, lex->create_list, lex->key_list, select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, @@ -2529,38 +2641,37 @@ unsent_create_error: #endif /*DONT_ALLOW_SHOW_COMMANDS*/ case SQLCOM_RENAME_TABLE: { + DBUG_ASSERT(first_table == all_tables && first_table != 0); TABLE_LIST *table; - if (check_db_used(thd,tables)) + if (check_db_used(thd, all_tables)) goto error; - for (table=tables ; table ; table=table->next->next) + for (table= first_table; table; table= table->next_local->next_local) { if (check_access(thd, ALTER_ACL | DROP_ACL, table->db, &table->grant.privilege,0,0) || - check_access(thd, INSERT_ACL | CREATE_ACL, table->next->db, - &table->next->grant.privilege,0,0)) + check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db, + &table->next_local->grant.privilege, 0, 0)) goto error; if (grant_option) { - TABLE_LIST old_list,new_list; + TABLE_LIST old_list, new_list; /* we do not need initialize old_list and new_list because we will come table[0] and table->next[0] there */ - old_list=table[0]; - new_list=table->next[0]; - old_list.next=new_list.next=0; - if (check_grant(thd, ALTER_ACL, &old_list, 0, UINT_MAX, 0) || - (!test_all_bits(table->next->grant.privilege, + old_list= table[0]; + new_list= table->next_local[0]; + if (check_grant(thd, ALTER_ACL, &old_list, 0, 1, 0) || + (!test_all_bits(table->next_local->grant.privilege, INSERT_ACL | CREATE_ACL) && - check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, - UINT_MAX, 0))) + check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0))) goto error; } } - query_cache_invalidate3(thd, tables, 0); + query_cache_invalidate3(thd, first_table, 0); if (end_active_trans(thd)) res= -1; - else if (mysql_rename_tables(thd,tables)) + else if (mysql_rename_tables(thd, first_table)) res= -1; break; } @@ -2568,7 +2679,7 @@ unsent_create_error: case SQLCOM_SHOW_BINLOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { if (check_global_access(thd, SUPER_ACL)) @@ -2579,38 +2690,40 @@ unsent_create_error: #endif #endif /* EMBEDDED_LIBRARY */ case SQLCOM_SHOW_CREATE: + DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { - if (check_db_used(thd, tables) || - check_access(thd, SELECT_ACL | EXTRA_ACL, tables->db, - &tables->grant.privilege,0,0)) + if (check_db_used(thd, all_tables) || + check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db, + &first_table->grant.privilege, 0, 0)) goto error; - res = mysqld_show_create(thd, tables); + res = mysqld_show_create(thd, first_table); break; } #endif case SQLCOM_CHECKSUM: { - if (check_db_used(thd,tables) || - check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables,0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables, 0)) goto error; /* purecov: inspected */ - res = mysql_checksum_table(thd, tables, &lex->check_opt); + res = mysql_checksum_table(thd, first_table, &lex->check_opt); break; } case SQLCOM_REPAIR: { - if (check_db_used(thd,tables) || - check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; - res = mysql_repair_table(thd, tables, &lex->check_opt); + res= mysql_repair_table(thd, first_table, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -2622,24 +2735,25 @@ unsent_create_error: } case SQLCOM_CHECK: { - if (check_db_used(thd,tables) || - check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables,0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables, 0)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; - res = mysql_check_table(thd, tables, &lex->check_opt); + res = mysql_check_table(thd, first_table, &lex->check_opt); break; } case SQLCOM_ANALYZE: { - if (check_db_used(thd,tables) || - check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; - res = mysql_analyze_table(thd, tables, &lex->check_opt); + res = mysql_analyze_table(thd, first_table, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -2652,17 +2766,17 @@ unsent_create_error: case SQLCOM_OPTIMIZE: { - if (check_db_used(thd,tables) || - check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0)) goto error; /* purecov: inspected */ thd->slow_command=TRUE; res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ? - mysql_recreate_table(thd, tables, 1) : - mysql_optimize_table(thd, tables, &lex->check_opt); + mysql_recreate_table(thd, first_table, 1) : + mysql_optimize_table(thd, first_table, &lex->check_opt); /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -2673,9 +2787,10 @@ unsent_create_error: break; } case SQLCOM_UPDATE: - if (update_precheck(thd, tables)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (update_precheck(thd, all_tables)) break; - res= mysql_update(thd,tables, + res= mysql_update(thd, all_tables, select_lex->item_list, lex->value_list, select_lex->where, @@ -2688,9 +2803,10 @@ unsent_create_error: break; case SQLCOM_UPDATE_MULTI: { - if ((res= multi_update_precheck(thd, tables))) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if ((res= multi_update_precheck(thd, all_tables))) break; - res= mysql_multi_update(thd,tables, + res= mysql_multi_update(thd, all_tables, &select_lex->item_list, &lex->value_list, select_lex->where, @@ -2701,67 +2817,81 @@ unsent_create_error: case SQLCOM_REPLACE: case SQLCOM_INSERT: { - if ((res= insert_precheck(thd, tables))) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if ((res= insert_precheck(thd, all_tables))) break; - res = mysql_insert(thd,tables,lex->field_list,lex->many_values, - select_lex->item_list, lex->value_list, - lex->duplicates); + res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values, + select_lex->item_list, lex->value_list, + (lex->value_list.elements ? + DUP_UPDATE : lex->duplicates)); if (thd->net.report_error) res= -1; + if (first_table->view && !first_table->contain_auto_increment) + thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it break; } case SQLCOM_REPLACE_SELECT: case SQLCOM_INSERT_SELECT: { - TABLE_LIST *first_local_table= (TABLE_LIST *) select_lex->table_list.first; - if ((res= insert_select_precheck(thd, tables))) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if ((res= insert_select_precheck(thd, all_tables))) break; /* Fix lock for first table */ - if (tables->lock_type == TL_WRITE_DELAYED) - tables->lock_type= TL_WRITE; + if (first_table->lock_type == TL_WRITE_DELAYED) + first_table->lock_type= TL_WRITE; /* Don't unlock tables until command is written to binary log */ select_lex->options|= SELECT_NO_UNLOCK; select_result *result; - unit->offset_limit_cnt= select_lex->offset_limit; - unit->select_limit_cnt= select_lex->select_limit+select_lex->offset_limit; - if (unit->select_limit_cnt < select_lex->select_limit) - unit->select_limit_cnt= HA_POS_ERROR; // No limit - - if (find_real_table_in_list(tables->next, tables->db, tables->real_name)) - { - /* Using same table for INSERT and SELECT */ - select_lex->options |= OPTION_BUFFER_RESULT; - } - + unit->set_limit(select_lex, select_lex); - if (!(res= open_and_lock_tables(thd, tables)) && - (result= new select_insert(tables->table, &lex->field_list, - lex->duplicates))) + if (!(res= open_and_lock_tables(thd, all_tables))) { - /* Skip first table, which is the table we are inserting in */ - lex->select_lex.table_list.first= (byte*) first_local_table->next; /* - insert/replace from SELECT give its SELECT_LEX for SELECT, - and item_list belong to SELECT + Is table which we are changing used somewhere in other parts of + query */ - lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; - res= handle_select(thd, lex, result); - /* revert changes for SP */ - lex->select_lex.table_list.first= (byte*) first_local_table; - lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; - delete result; + if (unique_table(first_table, all_tables->next_global)) + { + /* Using same table for INSERT and SELECT */ + select_lex->options |= OPTION_BUFFER_RESULT; + } + + if ((res= mysql_insert_select_prepare(thd))) + break; + if ((result= new select_insert(first_table, first_table->table, + &lex->field_list, lex->duplicates, + lex->duplicates == DUP_IGNORE))) + { + /* Skip first table, which is the table we are inserting in */ + lex->select_lex.table_list.first= (byte*) first_table->next_local; + /* + insert/replace from SELECT give its SELECT_LEX for SELECT, + and item_list belong to SELECT + */ + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + res= handle_select(thd, lex, result); + /* revert changes for SP */ + lex->select_lex.table_list.first= (byte*) first_table; + lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + delete result; + } if (thd->net.report_error) res= -1; } else res= -1; + + if (first_table->view && !first_table->contain_auto_increment) + thd->last_insert_id= 0; // do not show last insert ID if VIEW have not it + break; } case SQLCOM_TRUNCATE: - if (check_one_table_access(thd, DELETE_ACL, tables)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_one_table_access(thd, DELETE_ACL, all_tables)) goto error; /* Don't allow this within a transaction because we want to use @@ -2772,13 +2902,15 @@ unsent_create_error: send_error(thd,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS); goto error; } - res=mysql_truncate(thd, tables, 0); + + res= mysql_truncate(thd, first_table, 0); break; case SQLCOM_DELETE: { - if ((res= delete_precheck(thd, tables))) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if ((res= delete_precheck(thd, all_tables))) break; - res = mysql_delete(thd,tables, select_lex->where, + res = mysql_delete(thd, all_tables, select_lex->where, &select_lex->order_list, select_lex->select_limit, select_lex->options); if (thd->net.report_error) @@ -2787,13 +2919,13 @@ unsent_create_error: } case SQLCOM_DELETE_MULTI: { + DBUG_ASSERT(first_table == all_tables && first_table != 0); TABLE_LIST *aux_tables= (TABLE_LIST *)thd->lex->auxilliary_table_list.first; - TABLE_LIST *target_tbl; uint table_count; multi_delete *result; - if ((res= multi_delete_precheck(thd, tables, &table_count))) + if ((res= multi_delete_precheck(thd, all_tables, &table_count))) break; /* condition will be TRUE on SP re-excuting */ @@ -2806,28 +2938,9 @@ unsent_create_error: } thd->proc_info="init"; - if ((res=open_and_lock_tables(thd,tables))) + if ((res= open_and_lock_tables(thd, all_tables)) || + (res= mysql_multi_delete_prepare(thd))) break; - /* Fix tables-to-be-deleted-from list to point at opened tables */ - for (target_tbl= (TABLE_LIST*) aux_tables; - target_tbl; - target_tbl= target_tbl->next) - { - TABLE_LIST *orig= target_tbl->table_list; - target_tbl->table= orig->table; - /* - Multi-delete can't be constructed over-union => we always have - single SELECT on top and have to check underlying SELECTs of it - */ - if (lex->select_lex.check_updateable_in_subqueries(orig->db, - orig->real_name)) - { - my_error(ER_UPDATE_TABLE_USED, MYF(0), - orig->real_name); - res= -1; - break; - } - } if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables, table_count))) @@ -2853,9 +2966,10 @@ unsent_create_error: } case SQLCOM_DROP_TABLE: { + DBUG_ASSERT(first_table == all_tables && first_table != 0); if (!lex->drop_temporary) { - if (check_table_access(thd,DROP_ACL,tables,0)) + if (check_table_access(thd, DROP_ACL, all_tables, 0)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) { @@ -2876,21 +2990,23 @@ unsent_create_error: if (thd->slave_thread) lex->drop_if_exists= 1; } - res= mysql_rm_table(thd,tables,lex->drop_if_exists, lex->drop_temporary); + res= mysql_rm_table(thd, first_table, lex->drop_if_exists, + lex->drop_temporary); } break; case SQLCOM_DROP_INDEX: - if (check_one_table_access(thd, INDEX_ACL, tables)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_one_table_access(thd, INDEX_ACL, all_tables)) goto error; /* purecov: inspected */ if (end_active_trans(thd)) res= -1; else - res = mysql_drop_index(thd, tables, &lex->alter_info); + res = mysql_drop_index(thd, first_table, &lex->alter_info); break; case SQLCOM_SHOW_DATABASES: #if defined(DONT_ALLOW_SHOW_COMMANDS) send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else if ((specialflag & SPECIAL_SKIP_SHOW_DB) && check_global_access(thd, SHOW_DB_ACL)) @@ -2915,18 +3031,28 @@ unsent_create_error: res= mysqld_show_column_types(thd); break; case SQLCOM_SHOW_STATUS: - res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars, - OPT_GLOBAL, &LOCK_status); + STATUS_VAR tmp; + if (lex->option_type == OPT_GLOBAL) + { + pthread_mutex_lock(&LOCK_status); + calc_sum_of_all_status(&tmp); + } + res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS), + status_vars, OPT_GLOBAL, &LOCK_status, + (lex->option_type == OPT_GLOBAL ? + &tmp: &thd->status_var)); + if (lex->option_type == OPT_GLOBAL) + pthread_mutex_unlock(&LOCK_status); break; case SQLCOM_SHOW_VARIABLES: res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS), init_vars, lex->option_type, - &LOCK_global_system_variables); + &LOCK_global_system_variables, 0); break; case SQLCOM_SHOW_LOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { if (grant_option && check_access(thd, FILE_ACL, any_db,0,0,0)) @@ -2939,13 +3065,13 @@ unsent_create_error: /* FALL THROUGH */ #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { char *db=select_lex->db ? select_lex->db : thd->db; if (!db) { - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ goto error; /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' @@ -2969,8 +3095,9 @@ unsent_create_error: res= mysqld_extend_show_tables(thd,db, (lex->wild ? lex->wild->ptr() : NullS)); else - res= mysqld_show_tables(thd,db, - (lex->wild ? lex->wild->ptr() : NullS)); + res= mysqld_show_tables(thd, db, + (lex->wild ? lex->wild->ptr() : NullS), + lex->verbose); break; } #endif @@ -2984,40 +3111,42 @@ unsent_create_error: res= mysqld_show_collations(thd,(lex->wild ? lex->wild->ptr() : NullS)); break; case SQLCOM_SHOW_FIELDS: + DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { - char *db=tables->db; + char *db= first_table->db; remove_escape(db); // Fix escaped '_' - remove_escape(tables->real_name); + remove_escape(first_table->real_name); if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, - &tables->grant.privilege, 0, 0)) + &first_table->grant.privilege, 0, 0)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd, SELECT_ACL, tables, 2, UINT_MAX, 0)) + if (grant_option && check_grant(thd, SELECT_ACL, first_table, 2, UINT_MAX, 0)) goto error; - res= mysqld_show_fields(thd,tables, + res= mysqld_show_fields(thd, first_table, (lex->wild ? lex->wild->ptr() : NullS), lex->verbose); break; } #endif case SQLCOM_SHOW_KEYS: + DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - DBUG_VOID_RETURN; + goto error; #else { - char *db=tables->db; + char *db= first_table->db; remove_escape(db); // Fix escaped '_' - remove_escape(tables->real_name); + remove_escape(first_table->real_name); if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, - &tables->grant.privilege, 0, 0)) + &first_table->grant.privilege, 0, 0)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd, SELECT_ACL, tables, 2, UINT_MAX, 0)) + if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0)) goto error; - res= mysqld_show_keys(thd,tables); + res= mysqld_show_keys(thd, first_table); break; } #endif @@ -3027,12 +3156,13 @@ unsent_create_error: case SQLCOM_LOAD: { + DBUG_ASSERT(first_table == all_tables && first_table != 0); uint privilege= (lex->duplicates == DUP_REPLACE ? INSERT_ACL | DELETE_ACL : INSERT_ACL); if (!lex->local_file) { - if (check_access(thd,privilege | FILE_ACL,tables->db,0,0,0)) + if (check_access(thd, privilege | FILE_ACL, first_table->db, 0, 0, 0)) goto error; } else @@ -3043,19 +3173,21 @@ unsent_create_error: send_error(thd,ER_NOT_ALLOWED_COMMAND); goto error; } - if (check_one_table_access(thd, privilege, tables)) + if (check_one_table_access(thd, privilege, all_tables)) goto error; } - res=mysql_load(thd, lex->exchange, tables, lex->field_list, - lex->duplicates, (bool) lex->local_file, lex->lock_option); + res= mysql_load(thd, lex->exchange, first_table, lex->field_list, + lex->duplicates, (bool) lex->local_file, + lex->lock_option, lex->duplicates == DUP_IGNORE); break; } case SQLCOM_SET_OPTION: { List *lex_var_list= &lex->var_list; - if (tables && ((res= check_table_access(thd, SELECT_ACL, tables,0)) || - (res= open_and_lock_tables(thd,tables)))) + if (all_tables && + ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || + (res= open_and_lock_tables(thd, all_tables)))) break; if (lex->one_shot_set && not_all_support_one_shot(lex_var_list)) { @@ -3097,17 +3229,18 @@ purposes internal to the MySQL server", MYF(0)); break; case SQLCOM_LOCK_TABLES: unlock_locked_tables(thd); - if (check_db_used(thd,tables) || end_active_trans(thd)) + if (check_db_used(thd, all_tables) || end_active_trans(thd)) goto error; - if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, tables,0)) + if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0)) goto error; thd->in_lock_tables=1; thd->options|= OPTION_TABLE_LOCK; - if (!(res= open_and_lock_tables(thd, tables))) + + if (!(res= open_and_lock_tables(thd, all_tables))) { #ifdef HAVE_QUERY_CACHE if (thd->variables.query_cache_wlock_invalidate) - query_cache.invalidate_locked_for_write(tables); + query_cache.invalidate_locked_for_write(first_table); #endif /*HAVE_QUERY_CACHE*/ thd->locked_tables=thd->lock; thd->lock=0; @@ -3232,26 +3365,24 @@ purposes internal to the MySQL server", MYF(0)); res=mysqld_show_create_db(thd,lex->name,&lex->create_info); break; } - case SQLCOM_CREATE_FUNCTION: + case SQLCOM_CREATE_FUNCTION: // UDF function + { + sp_head *sph; if (check_access(thd,INSERT_ACL,"mysql",0,1,0)) break; #ifdef HAVE_DLOPEN + if ((sph= sp_find_function(thd, lex->spname))) + { + net_printf(thd, ER_UDF_EXISTS, lex->spname->m_name.str); + goto error; + } if (!(res = mysql_create_function(thd,&lex->udf))) send_ok(thd); #else res= -1; #endif break; - case SQLCOM_DROP_FUNCTION: - if (check_access(thd,DELETE_ACL,"mysql",0,1,0)) - break; -#ifdef HAVE_DLOPEN - if (!(res = mysql_drop_function(thd,&lex->udf.name))) - send_ok(thd); -#else - res= -1; -#endif - break; + } #ifndef NO_EMBEDDED_ACCESS_CHECKS case SQLCOM_DROP_USER: { @@ -3259,7 +3390,6 @@ purposes internal to the MySQL server", MYF(0)); break; if (!(res= mysql_drop_user(thd, lex->users_list))) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); @@ -3275,7 +3405,6 @@ purposes internal to the MySQL server", MYF(0)); break; if (!(res = mysql_revoke_all(thd, lex->users_list))) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); @@ -3289,34 +3418,12 @@ purposes internal to the MySQL server", MYF(0)); case SQLCOM_GRANT: { if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL, - tables && tables->db ? tables->db : select_lex->db, - tables ? &tables->grant.privilege : 0, - tables ? 0 : 1,0)) + ((first_table && first_table->db) ? + first_table->db : select_lex->db), + first_table ? &first_table->grant.privilege : 0, + first_table ? 0 : 1, 0)) goto error; - /* - Check that the user isn't trying to change a password for another - user if he doesn't have UPDATE privilege to the MySQL database - */ - - if (thd->user) // If not replication - { - LEX_USER *user; - List_iterator user_list(lex->users_list); - while ((user=user_list++)) - { - if (user->password.str && - (strcmp(thd->user,user->user.str) || - user->host.str && - my_strcasecmp(&my_charset_latin1, - user->host.str, thd->host_or_ip))) - { - if (check_access(thd, UPDATE_ACL, "mysql",0,1,0)) - goto error; - break; // We are allowed to do changes - } - } - } if (specialflag & SPECIAL_NO_RESOLVE) { LEX_USER *user; @@ -3330,24 +3437,21 @@ purposes internal to the MySQL server", MYF(0)); user->host.str); } } - if (tables) + if (first_table) { if (grant_option && check_grant(thd, (lex->grant | lex->grant_tot_col | GRANT_ACL), - tables, 0, UINT_MAX, 0)) + all_tables, 0, UINT_MAX, 0)) goto error; - if (!(res = mysql_table_grant(thd,tables,lex->users_list, lex->columns, - lex->grant, - lex->sql_command == SQLCOM_REVOKE))) + if (!(res = mysql_table_grant(thd, all_tables, lex->users_list, + lex->columns, lex->grant, + lex->sql_command == SQLCOM_REVOKE)) && + mysql_bin_log.is_open()) { - mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); - mysql_bin_log.write(&qinfo); - } + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); } } else @@ -3362,7 +3466,6 @@ purposes internal to the MySQL server", MYF(0)); lex->sql_command == SQLCOM_REVOKE); if (!res) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { thd->clear_error(); @@ -3389,14 +3492,14 @@ purposes internal to the MySQL server", MYF(0)); lex->no_write_to_binlog= 1; case SQLCOM_FLUSH: { - if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, tables)) + if (check_global_access(thd,RELOAD_ACL) || check_db_used(thd, all_tables)) goto error; /* reload_acl_and_cache() will tell us if we are allowed to write to the binlog or not. */ bool write_to_binlog; - if (reload_acl_and_cache(thd, lex->type, tables, &write_to_binlog)) + if (reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog)) send_error(thd, 0); else { @@ -3406,7 +3509,6 @@ purposes internal to the MySQL server", MYF(0)); */ if (!lex->no_write_to_binlog && write_to_binlog) { - mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); @@ -3418,7 +3520,7 @@ purposes internal to the MySQL server", MYF(0)); break; } case SQLCOM_KILL: - kill_one_thread(thd,lex->thread_id); + kill_one_thread(thd,lex->thread_id, lex->type & ONLY_KILL_QUERY); break; #ifndef NO_EMBEDDED_ACCESS_CHECKS case SQLCOM_SHOW_GRANTS: @@ -3432,34 +3534,37 @@ purposes internal to the MySQL server", MYF(0)); break; #endif case SQLCOM_HA_OPEN: - if (check_db_used(thd,tables) || - check_table_access(thd,SELECT_ACL, tables,0)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables) || + check_table_access(thd, SELECT_ACL, all_tables, 0)) goto error; - res = mysql_ha_open(thd, tables); + res= mysql_ha_open(thd, first_table); break; case SQLCOM_HA_CLOSE: - if (check_db_used(thd,tables)) + DBUG_ASSERT(first_table == all_tables && first_table != 0); + if (check_db_used(thd, all_tables)) goto error; - res = mysql_ha_close(thd, tables); + res= mysql_ha_close(thd, first_table); break; case SQLCOM_HA_READ: + DBUG_ASSERT(first_table == all_tables && first_table != 0); /* There is no need to check for table permissions here, because if a user has no permissions to read a table, he won't be able to open it (with SQLCOM_HA_OPEN) in the first place. */ - if (check_db_used(thd,tables)) + if (check_db_used(thd, all_tables)) goto error; - res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir, - lex->insert_list, lex->ha_rkey_mode, select_lex->where, - select_lex->select_limit, select_lex->offset_limit); + res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->backup_dir, + lex->insert_list, lex->ha_rkey_mode, select_lex->where, + select_lex->select_limit, select_lex->offset_limit); break; case SQLCOM_BEGIN: if (thd->locked_tables) { thd->lock=thd->locked_tables; - thd->locked_tables=0; // Will be automaticly closed + thd->locked_tables=0; // Will be automatically closed close_thread_tables(thd); // Free tables } if (end_active_trans(thd)) @@ -3532,11 +3637,353 @@ purposes internal to the MySQL server", MYF(0)); else res= -1; break; + case SQLCOM_CREATE_PROCEDURE: + case SQLCOM_CREATE_SPFUNCTION: + { + uint namelen; + char *name; + + if (!lex->sphead) + { + res= -1; // Shouldn't happen + break; + } + + if (! lex->sphead->m_db.str) + { + send_error(thd,ER_NO_DB_ERROR); + delete lex->sphead; + lex->sphead= 0; + goto error; + } + + name= lex->sphead->name(&namelen); +#ifdef HAVE_DLOPEN + if (lex->sphead->m_type == TYPE_ENUM_FUNCTION) + { + udf_func *udf = find_udf(name, namelen); + + if (udf) + { + net_printf(thd, ER_UDF_EXISTS, name); + delete lex->sphead; + lex->sphead= 0; + goto error; + } + } +#endif + if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && + !lex->sphead->m_has_return) + { + net_printf(thd, ER_SP_NORETURN, name); + delete lex->sphead; + lex->sphead= 0; + goto error; + } + + res= lex->sphead->create(thd); + switch (res) { + case SP_OK: + send_ok(thd); + lex->unit.cleanup(); + delete lex->sphead; + lex->sphead= 0; + break; + case SP_WRITE_ROW_FAILED: + net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name); + lex->unit.cleanup(); + delete lex->sphead; + lex->sphead= 0; + goto error; + case SP_NO_DB_ERROR: + net_printf(thd, ER_BAD_DB_ERROR, lex->sphead->m_db.str); + lex->unit.cleanup(); + delete lex->sphead; + lex->sphead= 0; + goto error; + default: + net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name); + lex->unit.cleanup(); + delete lex->sphead; + lex->sphead= 0; + goto error; + } + break; + } + case SQLCOM_CALL: + { + sp_head *sp; + + if (!(sp= sp_find_procedure(thd, lex->spname))) + { + net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", + lex->spname->m_qname.str); + goto error; + } + else + { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + st_sp_security_context save_ctx; +#endif + ha_rows select_limit; + uint smrx; + LINT_INIT(smrx); + + /* In case the arguments are subselects... */ + if (all_tables && + ((res= check_table_access(thd, SELECT_ACL, all_tables, 0)) || + (res= open_and_lock_tables(thd, all_tables)))) + { + break; + } + +#ifndef EMBEDDED_LIBRARY + /* + When executing substatements, they're assumed to send_error when + it happens, but not to send_ok. + */ + my_bool nsok= thd->net.no_send_ok; + thd->net.no_send_ok= TRUE; +#endif + if (sp->m_multi_results) + { + if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS)) + { + send_error(thd, ER_SP_BADSELECT); +#ifndef EMBEDDED_LIBRARY + thd->net.no_send_ok= nsok; +#endif + goto error; + } + smrx= thd->server_status & SERVER_MORE_RESULTS_EXISTS; + thd->server_status |= SERVER_MORE_RESULTS_EXISTS; + } + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + sp_change_security_context(thd, sp, &save_ctx); +#endif + select_limit= thd->variables.select_limit; + thd->variables.select_limit= HA_POS_ERROR; + + thd->row_count_func= 0; + res= sp->execute_procedure(thd, &lex->value_list); + + thd->variables.select_limit= select_limit; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + sp_restore_security_context(thd, sp, &save_ctx); +#endif + +#ifndef EMBEDDED_LIBRARY + thd->net.no_send_ok= nsok; +#endif + if (sp->m_multi_results) + { + if (! smrx) + thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS; + } + + if (res == 0) + send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 : thd->row_count_func)); + else + goto error; // Substatement should already have sent error + } + break; + } + case SQLCOM_ALTER_PROCEDURE: + case SQLCOM_ALTER_FUNCTION: + { + sp_head *sp; + st_sp_chistics chistics; + + memcpy(&chistics, &lex->sp_chistics, sizeof(chistics)); + if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) + sp= sp_find_procedure(thd, lex->spname); + else + sp= sp_find_function(thd, lex->spname); + mysql_reset_errors(thd); + if (! sp) + res= SP_KEY_NOT_FOUND; + else + { + if (check_sp_definer_access(thd, sp)) + { + res= -1; + break; + } + memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics)); + if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) + res= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); + else + res= sp_update_function(thd, lex->spname, &lex->sp_chistics); + } + switch (res) + { + case SP_OK: + send_ok(thd); + break; + case SP_KEY_NOT_FOUND: + net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), + lex->spname->m_qname.str); + goto error; + default: + net_printf(thd, ER_SP_CANT_ALTER, SP_COM_STRING(lex), + lex->spname->m_qname.str); + goto error; + } + break; + } + case SQLCOM_DROP_PROCEDURE: + case SQLCOM_DROP_FUNCTION: + { + sp_head *sp; + + if (lex->sql_command == SQLCOM_DROP_PROCEDURE) + sp= sp_find_procedure(thd, lex->spname); + else + sp= sp_find_function(thd, lex->spname); + mysql_reset_errors(thd); + if (! sp) + res= SP_KEY_NOT_FOUND; + else + { + if (check_sp_definer_access(thd, sp)) + { + res= -1; + break; + } + if (lex->sql_command == SQLCOM_DROP_PROCEDURE) + res= sp_drop_procedure(thd, lex->spname); + else + { + res= sp_drop_function(thd, lex->spname); +#ifdef HAVE_DLOPEN + if (res == SP_KEY_NOT_FOUND) + { + udf_func *udf = find_udf(lex->spname->m_name.str, + lex->spname->m_name.length); + if (udf) + { + if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0)) + goto error; + if (!(res = mysql_drop_function(thd,&lex->spname->m_name))) + { + send_ok(thd); + break; + } + } + } +#endif + } + } + switch (res) + { + case SP_OK: + send_ok(thd); + break; + case SP_KEY_NOT_FOUND: + if (lex->drop_if_exists) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), + SP_COM_STRING(lex), lex->spname->m_name.str); + res= 0; + send_ok(thd); + break; + } + net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), + lex->spname->m_qname.str); + goto error; + default: + net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex), + lex->spname->m_qname.str); + goto error; + } + break; + } + case SQLCOM_SHOW_CREATE_PROC: + { + res= -1; + if (lex->spname->m_name.length > NAME_LEN) + { + net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); + goto error; + } + res= sp_show_create_procedure(thd, lex->spname); + if (res != SP_OK) + { /* We don't distinguish between errors for now */ + net_printf(thd, ER_SP_DOES_NOT_EXIST, + SP_COM_STRING(lex), lex->spname->m_name.str); + res= 0; + goto error; + } + break; + } + case SQLCOM_SHOW_CREATE_FUNC: + { + if (lex->spname->m_name.length > NAME_LEN) + { + net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); + goto error; + } + res= sp_show_create_function(thd, lex->spname); + if (res != SP_OK) + { /* We don't distinguish between errors for now */ + net_printf(thd, ER_SP_DOES_NOT_EXIST, + SP_COM_STRING(lex), lex->spname->m_name.str); + res= 0; + goto error; + } + res= 0; + break; + } + case SQLCOM_SHOW_STATUS_PROC: + { + res= sp_show_status_procedure(thd, (lex->wild ? + lex->wild->ptr() : NullS)); + break; + } + case SQLCOM_SHOW_STATUS_FUNC: + { + res= sp_show_status_function(thd, (lex->wild ? + lex->wild->ptr() : NullS)); + break; + } + case SQLCOM_CREATE_VIEW: + { + res= mysql_create_view(thd, thd->lex->create_view_mode); + break; + } + case SQLCOM_DROP_VIEW: + { + if (check_table_access(thd, DROP_ACL, all_tables, 0)) + goto error; + if (end_active_trans(thd)) + { + res= -1; + break; + } + res= mysql_drop_view(thd, first_table, thd->lex->drop_mode); + break; + } + case SQLCOM_CREATE_TRIGGER: + { + /* We don't care much about trigger body at that point */ + delete lex->sphead; + lex->sphead= 0; + + res= mysql_create_or_drop_trigger(thd, all_tables, 1); + break; + } + case SQLCOM_DROP_TRIGGER: + { + res= mysql_create_or_drop_trigger(thd, all_tables, 0); + break; + } default: /* Impossible */ send_ok(thd); break; } - thd->proc_info="query end"; // QQ + thd->proc_info="query end"; if (thd->one_shot_set) { /* @@ -3561,11 +4008,38 @@ purposes internal to the MySQL server", MYF(0)); thd->one_shot_set= 0; } } + + /* + The return value for ROW_COUNT() is "implementation dependent" if + the statement is not DELETE, INSERT or UPDATE (or a CALL executing + such a statement), but -1 is what JDBC and ODBC wants. + */ + switch (lex->sql_command) { + case SQLCOM_UPDATE: + case SQLCOM_UPDATE_MULTI: + case SQLCOM_REPLACE: + case SQLCOM_INSERT: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_INSERT_SELECT: + case SQLCOM_DELETE: + case SQLCOM_DELETE_MULTI: + case SQLCOM_CALL: + break; + default: + thd->row_count_func= -1; + } + + /* + We end up here if res == 0 and send_ok() has been done, + or res != 0 and no send_error() has yet been done. + */ if (res < 0) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + send_error(thd,thd->killed_errno()); + DBUG_RETURN(res); error: - DBUG_VOID_RETURN; + /* We end up here if send_error() has already been done. */ + DBUG_RETURN(-1); } @@ -3576,28 +4050,29 @@ error: SYNOPSIS check_one_table_access() thd Thread handler - privilege requested privelage - tables table list of command + privilege requested privilege + all_tables global table list of query RETURN 0 - OK 1 - access denied, error is sent to client */ -int check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables) +bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) { - if (check_access(thd, privilege, tables->db, &tables->grant.privilege,0,0)) + if (check_access(thd, privilege, all_tables->db, + &all_tables->grant.privilege, 0, 0)) return 1; /* Show only 1 table for check_grant */ - if (grant_option && check_grant(thd, privilege, tables, 0, 1, 0)) + if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, 0)) return 1; /* Check rights on tables of subselect (if exists) */ TABLE_LIST *subselects_tables; - if ((subselects_tables= tables->next)) + if ((subselects_tables= all_tables->next_global)) { - if ((check_table_access(thd, SELECT_ACL, subselects_tables,0))) + if ((check_table_access(thd, SELECT_ACL, subselects_tables, 0))) return 1; } return 0; @@ -3627,13 +4102,13 @@ bool check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, bool dont_check_global_grants, bool no_errors) { - DBUG_ENTER("check_access"); - DBUG_PRINT("enter",("db: '%s' want_access: %lu master_access: %lu", - db ? db : "", want_access, thd->master_access)); #ifndef NO_EMBEDDED_ACCESS_CHECKS ulong db_access; #endif ulong dummy; + DBUG_ENTER("check_access"); + DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu", + db ? db : "", want_access, thd->master_access)); if (save_priv) *save_priv=0; else @@ -3641,8 +4116,9 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if ((!db || !db[0]) && !thd->db && !dont_check_global_grants) { + DBUG_PRINT("error",("No database")); if (!no_errors) - send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ + send_error(thd,ER_NO_DB_ERROR); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -3667,6 +4143,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, if (((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL)) || ! db && dont_check_global_grants) { // We can never grant this + DBUG_PRINT("error",("No possible access")); if (!no_errors) net_printf(thd,ER_ACCESS_DENIED_ERROR, thd->priv_user, @@ -3686,13 +4163,17 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_PRINT("info",("db_access: %lu", db_access)); /* Remove SHOW attribute and access rights we already have */ want_access &= ~(thd->master_access | EXTRA_ACL); + DBUG_PRINT("info",("db_access: %lu want_access: %lu", + db_access, want_access)); db_access= ((*save_priv=(db_access | thd->master_access)) & want_access); /* grant_option is set if there exists a single table or column grant */ if (db_access == want_access || - ((grant_option && !dont_check_global_grants) && + (grant_option && !dont_check_global_grants && !(want_access & ~(db_access | TABLE_ACLS)))) DBUG_RETURN(FALSE); /* Ok */ + + DBUG_PRINT("error",("Access denied")); if (!no_errors) net_printf(thd,ER_DBACCESS_DENIED_ERROR, thd->priv_user, @@ -3712,7 +4193,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, want_access Use should have any of these global rights WARNING - One gets access rigth if one has ANY of the rights in want_access + One gets access right if one has ANY of the rights in want_access This is useful as one in most cases only need one global right, but in some case we want to check if the user has SUPER or REPL_CLIENT_ACL rights. @@ -3750,7 +4231,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, uint found=0; ulong found_access=0; TABLE_LIST *org_tables=tables; - for (; tables ; tables=tables->next) + for (; tables; tables= tables->next_global) { if (tables->derived || (tables->table && (int)tables->table->tmp_table) || @@ -3783,6 +4264,42 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, return FALSE; } + +/* + Check if the given table has any of the asked privileges + + SYNOPSIS + check_some_access() + thd Thread handler + want_access Bitmap of possible privileges to check for + + RETURN + 0 ok + 1 error +*/ + + +bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table) +{ + ulong access; + DBUG_ENTER("check_some_access"); + + /* This loop will work as long as we have less than 32 privileges */ + for (access= 1; access < want_access ; access<<= 1) + { + if (access & want_access) + { + if (!check_access(thd, access, table->db, + &table->grant.privilege, 0, 1) && + !grant_option || !check_grant(thd, access, table, 0, 1, 1)) + DBUG_RETURN(0); + } + } + DBUG_PRINT("exit",("no matching access rights")); + DBUG_RETURN(1); +} + + bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list) { @@ -3791,7 +4308,7 @@ bool check_merge_table_access(THD *thd, char *db, { /* Check that all tables use the current database */ TABLE_LIST *tmp; - for (tmp=table_list; tmp ; tmp=tmp->next) + for (tmp= table_list; tmp; tmp= tmp->next_local) { if (!tmp->db || !tmp->db[0]) tmp->db=db; @@ -3805,7 +4322,7 @@ bool check_merge_table_access(THD *thd, char *db, static bool check_db_used(THD *thd,TABLE_LIST *tables) { - for (; tables ; tables=tables->next) + for (; tables; tables= tables->next_global) { if (!tables->db) { @@ -3819,6 +4336,41 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) return FALSE; } + +/* + Check if the given SP is owned by thd->priv_user/host, or priv_user is root. + QQ This is not quite complete, but it will do as a basic security check + for now. The question is exactly which rights should 'root' have? + Should root have access regardless of host for instance? + + SYNOPSIS + check_sp_definer_access() + thd Thread handler + sp The SP pointer + + RETURN + 0 ok + 1 error Error message has been sent +*/ + +static bool +check_sp_definer_access(THD *thd, sp_head *sp) +{ + LEX_STRING *usr, *hst; + + if (strcmp("root", thd->priv_user) == 0) + return FALSE; /* QQ Any root is ok now */ + usr= &sp->m_definer_user; + hst= &sp->m_definer_host; + if (strncmp(thd->priv_user, usr->str, usr->length) == 0 && + strncmp(thd->priv_host, hst->str, hst->length) == 0) + return FALSE; /* Both user and host must match */ + + my_error(ER_SP_ACCESS_DENIED_ERROR, MYF(0), sp->m_qname.str); + return TRUE; /* Not definer or root */ +} + + /**************************************************************************** Check stack size; Send error if there isn't enough stack to continue ****************************************************************************/ @@ -3883,6 +4435,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize) return 0; } + /**************************************************************************** Initialize global thd variables needed for query ****************************************************************************/ @@ -3915,13 +4468,13 @@ void mysql_reset_thd_for_next_command(THD *thd) DBUG_ENTER("mysql_reset_thd_for_next_command"); thd->free_list= 0; thd->select_number= 1; - thd->total_warn_count= 0; // Warnings for this query + thd->total_warn_count=0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; thd->sent_row_count= thd->examined_row_count= 0; thd->is_fatal_error= thd->rand_used= thd->time_zone_used= 0; thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS | - SERVER_QUERY_NO_INDEX_USED | - SERVER_QUERY_NO_GOOD_INDEX_USED); + SERVER_QUERY_NO_INDEX_USED | + SERVER_QUERY_NO_GOOD_INDEX_USED); thd->tmp_table_used= 0; if (opt_bin_log) reset_dynamic(&thd->user_var_events); @@ -3940,7 +4493,6 @@ mysql_init_select(LEX *lex) { DBUG_ASSERT(lex->result == 0); lex->exchange= 0; - lex->proc_list.first= 0; } } @@ -3954,6 +4506,7 @@ mysql_new_select(LEX *lex, bool move_down) select_lex->select_number= ++lex->thd->select_number; select_lex->init_query(); select_lex->init_select(); + select_lex->parent_lex= lex; if (move_down) { /* first select_lex of subselect or derived table */ @@ -3969,10 +4522,15 @@ mysql_new_select(LEX *lex, bool move_down) unit->link_prev= 0; unit->return_to= lex->current_select; select_lex->include_down(unit); - // TODO: assign resolve_mode for fake subquery after merging with new tree + /* TODO: assign resolve_mode for fake subquery after merging with new tree */ } else { + if (lex->current_select->order_list.first && !lex->current_select->braces) + { + net_printf(lex->thd, ER_WRONG_USAGE, "UNION", "ORDER BY"); + return 1; + } select_lex->include_neighbour(lex->current_select); SELECT_LEX_UNIT *unit= select_lex->master_unit(); SELECT_LEX *fake= unit->fake_select_lex; @@ -4040,6 +4598,8 @@ void mysql_init_multi_delete(LEX *lex) lex->select_lex.select_limit= lex->unit.select_limit_cnt= HA_POS_ERROR; lex->select_lex.table_list.save_and_clear(&lex->auxilliary_table_list); + lex->query_tables= 0; + lex->query_tables_last= &lex->query_tables; } @@ -4068,22 +4628,42 @@ void mysql_parse(THD *thd, char *inBuf, uint length) #endif { if (thd->net.report_error) + { send_error(thd, 0, NullS); + if (thd->lex->sphead) + { + if (lex != thd->lex) + thd->lex->sphead->restore_lex(thd); + delete thd->lex->sphead; + thd->lex->sphead= NULL; + } + } else { mysql_execute_command(thd); query_cache_end_of_result(thd); } } + lex->unit.cleanup(); } else { DBUG_PRINT("info",("Command aborted. Fatal_error: %d", thd->is_fatal_error)); query_cache_abort(&thd->net); + lex->unit.cleanup(); + if (thd->lex->sphead) + { + /* Clean up after failed stored procedure/function */ + if (lex != thd->lex) + thd->lex->sphead->restore_lex(thd); + delete thd->lex->sphead; + thd->lex->sphead= NULL; + } } thd->proc_info="freeing items"; thd->end_statement(); + thd->cleanup_after_query(); DBUG_ASSERT(thd->change_list.is_empty()); } DBUG_VOID_RETURN; @@ -4104,17 +4684,20 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) { LEX *lex= thd->lex; bool error= 0; + DBUG_ENTER("mysql_test_parse_for_slave"); mysql_init_query(thd, (uchar*) inBuf, length); if (!yyparse((void*) thd) && ! thd->is_fatal_error && all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) - error= 1; /* Ignore question */ + error= 1; /* Ignore question */ thd->end_statement(); - return error; + thd->cleanup_after_query(); + DBUG_RETURN(error); } #endif + /* Calculate interval lengths. Strip trailing spaces from all strings. @@ -4156,6 +4739,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, register create_field *new_field; LEX *lex= thd->lex; uint allowed_type_modifier=0; + uint sign_len; char warn_buff[MYSQL_ERRMSG_SIZE]; DBUG_ENTER("add_field_to_list"); @@ -4247,9 +4831,19 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->comment.str= (char*) comment->str; new_field->comment.length=comment->length; } + /* + Set flag if this field doesn't have a default value + Enum values has always the first value as a default (set in + make_empty_rec(). + */ + if (!default_value && !(type_modifier & AUTO_INCREMENT_FLAG) && + (type_modifier & NOT_NULL_FLAG) && type != FIELD_TYPE_TIMESTAMP && + type != FIELD_TYPE_ENUM) + new_field->flags|= NO_DEFAULT_VALUE_FLAG; + if (length && !(new_field->length= (uint) atoi(length))) length=0; /* purecov: inspected */ - uint sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1; + sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1; if (new_field->length && new_field->decimals && new_field->length < new_field->decimals+1 && @@ -4302,7 +4896,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->sql_type= FIELD_TYPE_BLOB; sprintf(warn_buff, ER(ER_AUTO_CONVERT), field_name, "CHAR", (cs == &my_charset_bin) ? "BLOB" : "TEXT"); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_AUTO_CONVERT, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, warn_buff); /* fall through */ case FIELD_TYPE_BLOB: @@ -4423,11 +5017,11 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, If we have TIMESTAMP NULL column without explicit DEFAULT value we treat it as having DEFAULT NULL attribute. */ - new_field->unireg_check= on_update_value ? - Field::TIMESTAMP_UN_FIELD : - (new_field->flags & NOT_NULL_FLAG ? - Field::TIMESTAMP_OLD_FIELD: - Field::NONE); + new_field->unireg_check= (on_update_value ? + Field::TIMESTAMP_UN_FIELD : + (new_field->flags & NOT_NULL_FLAG ? + Field::TIMESTAMP_OLD_FIELD: + Field::NONE)); } break; case FIELD_TYPE_DATE: // Old date type @@ -4601,6 +5195,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc) order->asc = asc; order->free_me=0; order->used=0; + order->counter_used= 0; list.link_in_list((byte*) order,(byte**) &order->next); DBUG_RETURN(0); } @@ -4636,6 +5231,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, { register TABLE_LIST *ptr; char *alias_str; + LEX *lex= thd->lex; DBUG_ENTER("add_table_to_list"); if (!table) @@ -4689,6 +5285,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX); ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES); ptr->derived= table->sel; + ptr->select_lex= lex->current_select; ptr->cacheable_table= 1; if (use_index_arg) ptr->use_index=(List *) thd->memdup((gptr) use_index_arg, @@ -4702,7 +5299,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, { for (TABLE_LIST *tables=(TABLE_LIST*) table_list.first ; tables ; - tables=tables->next) + tables=tables->next_local) { if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) && !strcmp(ptr->db, tables->db)) @@ -4712,11 +5309,245 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, } } } - table_list.link_in_list((byte*) ptr, (byte**) &ptr->next); + /* Link table in local list (list for current select) */ + table_list.link_in_list((byte*) ptr, (byte**) &ptr->next_local); + /* Link table in global list (all used tables) */ + lex->add_to_query_tables(ptr); + DBUG_RETURN(ptr); +} + + +/* + Initialize a new table list for a nested join + + SYNOPSIS + init_table_list() + thd current thread + + DESCRIPTION + The function initializes a structure of the TABLE_LIST type + for a nested join. It sets up its nested join list as empty. + The created structure is added to the front of the current + join list in the st_select_lex object. Then the function + changes the current nest level for joins to refer to the newly + created empty list after having saved the info on the old level + in the initialized structure. + + RETURN VALUE + 0, if success + 1, otherwise +*/ + +bool st_select_lex::init_nested_join(THD *thd) +{ + TABLE_LIST *ptr; + NESTED_JOIN *nested_join; + DBUG_ENTER("init_nested_join"); + + if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))) || + !(nested_join= ptr->nested_join= + (NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN)))) + DBUG_RETURN(1); + join_list->push_front(ptr); + ptr->embedding= embedding; + ptr->join_list= join_list; + embedding= ptr; + join_list= &nested_join->join_list; + join_list->empty(); + DBUG_RETURN(0); +} + + +/* + End a nested join table list + + SYNOPSIS + end_nested_join() + thd current thread + + DESCRIPTION + The function returns to the previous join nest level. + If the current level contains only one member, the function + moves it one level up, eliminating the nest. + + RETURN VALUE + Pointer to TABLE_LIST element added to the total table list, if success + 0, otherwise +*/ + +TABLE_LIST *st_select_lex::end_nested_join(THD *thd) +{ + TABLE_LIST *ptr; + DBUG_ENTER("end_nested_join"); + ptr= embedding; + join_list= ptr->join_list; + embedding= ptr->embedding; + NESTED_JOIN *nested_join= ptr->nested_join; + if (nested_join->join_list.elements == 1) + { + TABLE_LIST *embedded= nested_join->join_list.head(); + join_list->pop(); + embedded->join_list= join_list; + embedded->embedding= embedding; + join_list->push_front(embedded); + ptr= embedded; + } DBUG_RETURN(ptr); } +/* + Nest last join operation + + SYNOPSIS + nest_last_join() + thd current thread + + DESCRIPTION + The function nest last join operation as if it was enclosed in braces. + + RETURN VALUE + Pointer to TABLE_LIST element created for the new nested join, if success + 0, otherwise +*/ + +TABLE_LIST *st_select_lex::nest_last_join(THD *thd) +{ + TABLE_LIST *ptr; + NESTED_JOIN *nested_join; + DBUG_ENTER("nest_last_join"); + + if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))) || + !(nested_join= ptr->nested_join= + (NESTED_JOIN *) thd->calloc(sizeof(NESTED_JOIN)))) + DBUG_RETURN(0); + ptr->embedding= embedding; + ptr->join_list= join_list; + List *embedded_list= &nested_join->join_list; + embedded_list->empty(); + for (int i=0; i < 2; i++) + { + TABLE_LIST *table= join_list->pop(); + table->join_list= embedded_list; + table->embedding= ptr; + embedded_list->push_back(table); + } + join_list->push_front(ptr); + nested_join->used_tables= nested_join->not_null_tables= (table_map) 0; + DBUG_RETURN(ptr); +} + + +/* + Save names for a join with using clause + + SYNOPSIS + save_names_for_using_list + tab1 left table in join + tab2 right table in join + + DESCRIPTION + The function saves the full names of the tables in st_select_lex + to be able to build later an on expression to replace the using clause. + + RETURN VALUE + None +*/ + +void st_select_lex::save_names_for_using_list(TABLE_LIST *tab1, + TABLE_LIST *tab2) +{ + while (tab1->nested_join) + { + tab1= tab1->nested_join->join_list.head(); + } + db1= tab1->db; + table1= tab1->alias; + while (tab2->nested_join) + { + TABLE_LIST *next; + List_iterator_fast it(tab2->nested_join->join_list); + tab2= it++; + while ((next= it++)) + tab2= next; + } + db2= tab2->db; + table2= tab2->alias; +} + + +/* + Add a table to the current join list + + SYNOPSIS + add_joined_table() + table the table to add + + DESCRIPTION + The function puts a table in front of the current join list + of st_select_lex object. + Thus, joined tables are put into this list in the reverse order + (the most outer join operation follows first). + + RETURN VALUE + None +*/ + +void st_select_lex::add_joined_table(TABLE_LIST *table) +{ + DBUG_ENTER("add_joined_table"); + join_list->push_front(table); + table->join_list= join_list; + table->embedding= embedding; + DBUG_VOID_RETURN; +} + + +/* + Convert a right join into equivalent left join + + SYNOPSIS + convert_right_join() + thd current thread + + DESCRIPTION + The function takes the current join list t[0],t[1] ... and + effectively converts it into the list t[1],t[0] ... + Although the outer_join flag for the new nested table contains + JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join + operation. + + EXAMPLES + SELECT * FROM t1 RIGHT JOIN t2 ON on_expr => + SELECT * FROM t2 LEFT JOIN t1 ON on_expr + + SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr => + SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr + + SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr => + SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr + + SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 => + SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1 + + RETURN + Pointer to the table representing the inner table, if success + 0, otherwise +*/ + +TABLE_LIST *st_select_lex::convert_right_join() +{ + TABLE_LIST *tab2= join_list->pop(); + TABLE_LIST *tab1= join_list->pop(); + DBUG_ENTER("convert_right_join"); + + join_list->push_front(tab2); + join_list->push_front(tab1); + tab1->outer_join|= JOIN_TYPE_RIGHT; + + DBUG_RETURN(tab1); +} + /* Set lock for all tables in current select level @@ -4737,9 +5568,9 @@ void st_select_lex::set_lock_for_tables(thr_lock_type lock_type) DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type, for_update)); - for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first ; - tables ; - tables=tables->next) + for (TABLE_LIST *tables= (TABLE_LIST*) table_list.first; + tables; + tables= tables->next_local) { tables->lock_type= lock_type; tables->updating= for_update; @@ -4756,7 +5587,7 @@ void add_join_on(TABLE_LIST *b,Item *expr) b->on_expr=expr; else { - // This only happens if you have both a right and left join + /* This only happens if you have both a right and left join */ b->on_expr=new Item_cond_and(b->on_expr,expr); } b->on_expr->top_level_item(); @@ -4771,7 +5602,7 @@ void add_join_on(TABLE_LIST *b,Item *expr) add_join_natural() a Table to do normal join with b Do normal join with this table - + IMPLEMENTATION This function just marks that table b should be joined with a. The function setup_cond() will create in b->on_expr a list @@ -4836,7 +5667,6 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, */ tmp_write_to_binlog= 0; mysql_log.new_file(1); - mysql_update_log.new_file(1); mysql_bin_log.new_file(1); mysql_slow_log.new_file(1); #ifdef HAVE_REPLICATION @@ -4859,7 +5689,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, if (options & REFRESH_QUERY_CACHE_FREE) { query_cache.pack(); // FLUSH QUERY CACHE - options &= ~REFRESH_QUERY_CACHE; //don't flush all cache, just free memory + options &= ~REFRESH_QUERY_CACHE; // Don't flush cache, just free memory } if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE)) { @@ -4939,7 +5769,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, This is written such that we have a short lock on LOCK_thread_count */ -void kill_one_thread(THD *thd, ulong id) +void kill_one_thread(THD *thd, ulong id, bool only_kill_query) { THD *tmp; uint error=ER_NO_SUCH_THREAD; @@ -4959,7 +5789,7 @@ void kill_one_thread(THD *thd, ulong id) if ((thd->master_access & SUPER_ACL) || !strcmp(thd->user,tmp->user)) { - tmp->awake(1 /*prepare to die*/); + tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION); error=0; } else @@ -4993,6 +5823,13 @@ static void refresh_status(void) (char*) &dflt_key_cache_var)); *(ulong*) value= 0; } + else if (ptr->type == SHOW_LONG_STATUS) + { + THD *thd= current_thd; + /* We must update the global status before cleaning up the thread */ + add_to_status(&global_status_var, &thd->status_var); + bzero((char*) &thd->status_var, sizeof(thd->status_var)); + } } pthread_mutex_unlock(&LOCK_status); } @@ -5137,7 +5974,6 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys) List fields; ALTER_INFO alter_info; alter_info.flags= ALTER_ADD_INDEX; - alter_info.is_simple= 0; HA_CREATE_INFO create_info; DBUG_ENTER("mysql_create_index"); bzero((char*) &create_info,sizeof(create_info)); @@ -5161,7 +5997,6 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) create_info.default_table_charset= thd->variables.collation_database; alter_info->clear(); alter_info->flags= ALTER_DROP_INDEX; - alter_info->is_simple= 0; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name, &create_info, table_list, fields, keys, 0, (ORDER*)0, @@ -5175,7 +6010,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) SYNOPSIS multi_update_precheck() thd Thread handler - tables Global table list + tables Global/local table list (have to be the same) RETURN VALUE 0 OK @@ -5185,12 +6020,11 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) int multi_update_precheck(THD *thd, TABLE_LIST *tables) { - DBUG_ENTER("multi_update_precheck"); const char *msg= 0; TABLE_LIST *table; LEX *lex= thd->lex; SELECT_LEX *select_lex= &lex->select_lex; - TABLE_LIST *update_list= (TABLE_LIST*)select_lex->table_list.first; + DBUG_ENTER("multi_update_precheck"); if (select_lex->item_list.elements != lex->value_list.elements) { @@ -5201,7 +6035,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) Ensure that we have UPDATE or SELECT privilege for each table The exact privilege is checked in mysql_multi_update() */ - for (table= update_list; table; table= table->next) + for (table= tables; table; table= table->next_local) { if (table->derived) table->grant.privilege= SELECT_ACL; @@ -5209,17 +6043,12 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) &table->grant.privilege, 0, 1) || grant_option && check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) && - (check_access(thd, SELECT_ACL, table->db, - &table->grant.privilege, 0, 0) || - grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) + (check_access(thd, SELECT_ACL, table->db, + &table->grant.privilege, 0, 0) || + grant_option && check_grant(thd, SELECT_ACL, table, 0, 1, 0))) DBUG_RETURN(1); - /* - We assign following flag only to copy of table, because it will - be checked only if query contains subqueries i.e. only if copy exists - */ - if (table->table_list) - table->table_list->table_in_update_from_clause= 1; + table->table_in_first_from_clause= 1; } /* Is there tables of subqueries? @@ -5227,19 +6056,9 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) if (&lex->select_lex != lex->all_selects_list) { DBUG_PRINT("info",("Checking sub query list")); - for (table= tables; table; table= table->next) + for (table= tables; table; table= table->next_global) { - if (table->table_in_update_from_clause) - { - /* - If we check table by local TABLE_LIST copy then we should copy - grants to global table list, because it will be used for table - opening. - */ - if (table->table_list) - table->grant= table->table_list->grant; - } - else if (!table->derived) + if (!table->table_in_first_from_clause && table->derived) { if (check_access(thd, SELECT_ACL, table->db, &table->grant.privilege, 0, 0) || @@ -5268,7 +6087,7 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) SYNOPSIS multi_delete_precheck() thd Thread handler - tables Global table list + tables Global/local table list table_count Pointer to table counter RETURN VALUE @@ -5278,12 +6097,11 @@ int multi_update_precheck(THD *thd, TABLE_LIST *tables) */ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) { - DBUG_ENTER("multi_delete_precheck"); SELECT_LEX *select_lex= &thd->lex->select_lex; TABLE_LIST *aux_tables= (TABLE_LIST *)thd->lex->auxilliary_table_list.first; - TABLE_LIST *delete_tables= (TABLE_LIST *)select_lex->table_list.first; TABLE_LIST *target_tbl; + DBUG_ENTER("multi_delete_precheck"); *table_count= 0; @@ -5298,12 +6116,12 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); DBUG_RETURN(-1); } - for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next) + for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local) { (*table_count)++; /* All tables in aux_tables must be found in FROM PART */ TABLE_LIST *walk; - for (walk= delete_tables; walk; walk= walk->next) + for (walk= tables; walk; walk= walk->next_local) { if (!my_strcasecmp(table_alias_charset, target_tbl->alias, walk->alias) && @@ -5316,14 +6134,8 @@ int multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) "MULTI DELETE"); DBUG_RETURN(-1); } - if (walk->derived) - { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), target_tbl->real_name, - "DELETE"); - DBUG_RETURN(-1); - } walk->lock_type= target_tbl->lock_type; - target_tbl->table_list= walk; // Remember corresponding table + target_tbl->correspondent_table= walk; // Remember corresponding table } DBUG_RETURN(0); } @@ -5427,9 +6239,9 @@ int insert_precheck(THD *thd, TABLE_LIST *tables) LEX *lex= thd->lex; DBUG_ENTER("insert_precheck"); - ulong privilege= INSERT_ACL | - (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) | - (lex->duplicates == DUP_UPDATE ? UPDATE_ACL : 0); + ulong privilege= (INSERT_ACL | + (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) | + (lex->value_list.elements ? UPDATE_ACL : 0)); if (check_one_table_access(thd, privilege, tables)) DBUG_RETURN(1); @@ -5484,33 +6296,24 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables, /* Check permissions for used tables in CREATE TABLE ... SELECT */ /* - For temporary tables or PREPARED STATEMETNS we don't have to check - if the created table exists + Only do the check for PS, becasue we on execute we have to check that + against the opened tables to ensure we don't use a table that is part + of the view (which can only be done after the table has been opened). */ - if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && - ! thd->current_arena->is_stmt_prepare() && - find_real_table_in_list(tables, create_table->db, - create_table->real_name)) - { - net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name); - - goto err; - } - if (lex->create_info.used_fields & HA_CREATE_USED_UNION) + if (thd->current_arena->is_stmt_prepare()) { - TABLE_LIST *tab; - for (tab= tables; tab; tab= tab->next) + /* + For temporary tables we don't have to check if the created table exists + */ + if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && + find_table_in_global_list(tables, create_table->db, + create_table->real_name)) { - if (find_real_table_in_list((TABLE_LIST*) lex->create_info. - merge_list.first, - tables->db, tab->real_name)) - { - net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); - goto err; - } - } - } + net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name); + goto err; + } + } if (tables && check_table_access(thd, SELECT_ACL, tables,0)) goto err; } @@ -5526,7 +6329,7 @@ err: SYNOPSIS negate_expression() - thd therad handler + thd thread handler expr expression for negation RETURN diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d842b4b66bb..fe5ce7640ea 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -35,6 +35,10 @@ #include "sql_acl.h" #include "lex_symbol.h" #include "item_create.h" +#include "sp_head.h" +#include "sp_pcontext.h" +#include "sp_rcontext.h" +#include "sp.h" #include #include @@ -83,10 +87,14 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) enum Item_udftype udf_type; CHARSET_INFO *charset; thr_lock_type lock_type; - interval_type interval; + interval_type interval, interval_time_st; timestamp_type date_time_type; st_select_lex *select_lex; chooser_compare_func_creator boolfunc2creator; + struct sp_cond_type *spcondtype; + struct { int vars, conds, hndlrs, curs; } spblock; + sp_name *spname; + struct st_lex *lex; } %{ @@ -127,6 +135,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token AVG_SYM %token BEGIN_SYM %token BINLOG_SYM +%token CALL_SYM %token CHANGE %token CLIENT_SYM %token COMMENT_SYM @@ -136,7 +145,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CREATE %token CROSS %token CUBE_SYM +%token DEFINER_SYM %token DELETE_SYM +%token DETERMINISTIC_SYM %token DUAL_SYM %token DO_SYM %token DROP @@ -167,6 +178,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SHOW %token SLAVE %token SNAPSHOT_SYM +%token SQL_SYM %token SQL_THREAD %token START_SYM %token STD_SYM @@ -182,6 +194,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ACTION %token AGGREGATE_SYM +%token ALGORITHM_SYM %token ALL %token AND_SYM %token AS @@ -200,6 +213,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token BYTE_SYM %token CACHE_SYM %token CASCADE +%token CASCADED %token CAST_SYM %token CHARSET %token CHECKSUM_SYM @@ -210,11 +224,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token COLUMNS %token COLUMN_SYM %token CONCURRENT +%token CONDITION_SYM +%token CONNECTION_SYM %token CONSTRAINT +%token CONTAINS_SYM +%token CONTINUE_SYM %token CONVERT_SYM %token CURRENT_USER %token DATABASES %token DATA_SYM +%token DECLARE_SYM %token DEFAULT %token DELAYED_SYM %token DELAY_KEY_WRITE_SYM @@ -226,20 +245,24 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token DISTINCT %token DUPLICATE_SYM %token DYNAMIC_SYM +%token EACH_SYM %token ENABLE_SYM %token ENCLOSED %token ESCAPED %token DIRECTORY_SYM %token ESCAPE_SYM %token EXISTS +%token EXIT_SYM %token EXTENDED_SYM %token FALSE_SYM +%token FETCH_SYM %token FILE_SYM %token FIRST_SYM %token FIXED_SYM %token FLOAT_NUM %token FORCE_SYM %token FOREIGN +%token FOUND_SYM %token FROM %token FULL %token FULLTEXT_SYM @@ -262,8 +285,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token INFILE %token INNER_SYM %token INNOBASE_SYM +%token INOUT_SYM %token INTO %token IN_SYM +%token INVOKER_SYM %token ISOLATION %token JOIN_SYM %token KEYS @@ -273,14 +298,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token LEAVES %token LEVEL_SYM %token LEX_HOSTNAME +%token LANGUAGE_SYM %token LIKE %token LINES %token LOCAL_SYM +%token LOCATOR_SYM %token LOG_SYM %token LOGS_SYM %token LONG_NUM %token LONG_SYM %token LOW_PRIORITY +%token MERGE_SYM %token MASTER_HOST_SYM %token MASTER_USER_SYM %token MASTER_LOG_FILE_SYM @@ -305,6 +333,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MEDIUM_SYM %token MIN_ROWS %token NAMES_SYM +%token NAME_SYM %token NATIONAL_SYM %token NATURAL %token NDBCLUSTER_SYM @@ -325,6 +354,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token OR_SYM %token OR_OR_CONCAT %token ORDER_SYM +%token OUT_SYM %token OUTER %token OUTFILE %token DUMPFILE @@ -341,6 +371,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token RAID_CHUNKS %token RAID_CHUNKSIZE %token READ_SYM +%token READS_SYM %token REAL_NUM %token REFERENCES %token REGEXP @@ -356,6 +387,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ROW_FORMAT_SYM %token ROW_SYM %token RTREE_SYM +%token SECURITY_SYM %token SET %token SEPARATOR_SYM %token SERIAL_SYM @@ -364,6 +396,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SIMPLE_SYM %token SHUTDOWN %token SPATIAL_SYM +%token SPECIFIC_SYM +%token SQLEXCEPTION_SYM +%token SQLSTATE_SYM +%token SQLWARNING_SYM %token SSL_SYM %token STARTING %token STATUS_SYM @@ -374,11 +410,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token TABLE_SYM %token TABLESPACE %token TEMPORARY +%token TEMPTABLE_SYM %token TERMINATED %token TEXT_STRING %token TO_SYM %token TRAILING %token TRANSACTION_SYM +%token TRIGGER_SYM %token TRUE_SYM %token TYPE_SYM %token TYPES_SYM @@ -386,11 +424,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token FUNC_ARG1 %token FUNC_ARG2 %token FUNC_ARG3 -%token UDF_RETURNS_SYM +%token RETURN_SYM +%token RETURNS_SYM %token UDF_SONAME_SYM -%token UDF_SYM +%token UDF_RETURNS_SYM +%token FUNCTION_SYM %token UNCOMMITTED_SYM +%token UNDEFINED_SYM %token UNDERSCORE_CHARSET +%token UNDO_SYM %token UNICODE_SYM %token UNION_SYM %token UNIQUE_SYM @@ -401,6 +443,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token VALUE_SYM %token VALUES %token VARIABLES +%token VIEW_SYM %token WHERE %token WITH %token WRITE_SYM @@ -408,6 +451,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token X509_SYM %token XOR %token COMPRESSED_SYM +%token ROW_COUNT_SYM %token ERRORS %token WARNINGS @@ -444,6 +488,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token STRING_SYM %token TEXT_SYM %token TIMESTAMP +%token TIMESTAMP_ADD +%token TIMESTAMP_DIFF %token TIME_SYM %token TINYBLOB %token TINYINT @@ -490,6 +536,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token FIELD_FUNC %token FORMAT_SYM %token FOR_SYM +%token FRAC_SECOND_SYM %token FROM_UNIXTIME %token GEOMCOLLFROMTEXT %token GEOMFROMTEXT @@ -518,6 +565,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MINUTE_SECOND_SYM %token MINUTE_SYM %token MODE_SYM +%token MODIFIES_SYM %token MODIFY_SYM %token MONTH_SYM %token MLINEFROMTEXT @@ -535,6 +583,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token POLYGON %token POSITION_SYM %token PROCEDURE +%token QUARTER_SYM %token RAND %token REPLACE %token RIGHT @@ -546,12 +595,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SUBSTRING %token SUBSTRING_INDEX %token TRIM -%token UDA_CHAR_SUM -%token UDA_FLOAT_SUM -%token UDA_INT_SUM -%token UDF_CHAR_FUNC -%token UDF_FLOAT_FUNC -%token UDF_INT_FUNC %token UNIQUE_USERS %token UNIX_TIMESTAMP %token USER @@ -575,6 +618,20 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SQL_SMALL_RESULT %token SQL_BUFFER_RESULT +%token CURSOR_SYM +%token ELSEIF_SYM +%token ITERATE_SYM +%token GOTO_SYM +%token LABEL_SYM +%token LEAVE_SYM +%token LOOP_SYM +%token REPEAT_SYM +%token UNTIL_SYM +%token WHILE_SYM +%token ASENSITIVE_SYM +%token INSENSITIVE_SYM +%token SENSITIVE_SYM + %token ISSUER_SYM %token SUBJECT_SYM %token CIPHER_SYM @@ -600,6 +657,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component key_cache_name + sp_opt_label %type opt_table_alias @@ -634,17 +692,20 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type literal text_literal insert_ident order_ident simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr - table_wild no_in_expr expr_expr simple_expr no_and_expr + table_wild no_in_expr expr_expr simple_expr no_and_expr udf_expr using_list expr_or_default set_expr_or_default interval_expr param_marker singlerow_subselect singlerow_subselect_init exists_subselect exists_subselect_init geometry_function signed_literal now_or_signed_literal opt_escape + sp_opt_default + simple_ident_nospvar simple_ident_q %type NUM_literal %type - expr_list udf_expr_list when_list ident_list ident_list_arg + expr_list udf_expr_list udf_expr_list2 when_list + ident_list ident_list_arg %type key_type opt_unique_or_fulltext constraint_key_type @@ -660,14 +721,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type join_table_list join_table - -%type - UDF_CHAR_FUNC UDF_FLOAT_FUNC UDF_INT_FUNC - UDA_CHAR_SUM UDA_FLOAT_SUM UDA_INT_SUM + table_factor table_ref %type date_time_type; %type interval +%type interval_time_st + %type storage_engines %type row_types @@ -711,7 +771,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); select_item_list select_item values_list no_braces opt_limit_clause delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item - when_list2 expr_list2 handler + when_list2 expr_list2 udf_expr_list3 handler opt_precision opt_ignore opt_column opt_restrict grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock @@ -732,8 +792,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); subselect_end select_var_list select_var_list_init help opt_len opt_extended_describe prepare prepare_src execute deallocate + statement sp_suid opt_view_list view_list or_replace algorithm + sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic END_OF_INPUT +%type call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt +%type sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list +%type sp_cond sp_hcond +%type sp_decls sp_decl +%type sp_cursor_stmt +%type sp_name + %type '-' '+' '*' '/' '%' '(' ')' ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_CONCAT BETWEEN_SYM CASE_SYM @@ -759,10 +828,16 @@ query: | verb_clause END_OF_INPUT {}; verb_clause: + statement + | begin + ; + +/* Verb clauses, except begin */ +statement: alter | analyze | backup - | begin + | call | change | check | checksum @@ -919,163 +994,1411 @@ master_defs: master_def | master_defs ',' master_def; -master_def: - MASTER_HOST_SYM EQ TEXT_STRING_sys - { - Lex->mi.host = $3.str; - } - | - MASTER_USER_SYM EQ TEXT_STRING_sys - { - Lex->mi.user = $3.str; - } - | - MASTER_PASSWORD_SYM EQ TEXT_STRING_sys - { - Lex->mi.password = $3.str; - } - | - MASTER_PORT_SYM EQ ULONG_NUM - { - Lex->mi.port = $3; - } - | - MASTER_CONNECT_RETRY_SYM EQ ULONG_NUM - { - Lex->mi.connect_retry = $3; - } - | MASTER_SSL_SYM EQ ULONG_NUM - { - Lex->mi.ssl= $3 ? - LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE; - } - | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys - { - Lex->mi.ssl_ca= $3.str; - } - | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys - { - Lex->mi.ssl_capath= $3.str; - } - | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys - { - Lex->mi.ssl_cert= $3.str; - } - | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys - { - Lex->mi.ssl_cipher= $3.str; - } - | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys - { - Lex->mi.ssl_key= $3.str; - } - | - master_file_def - ; +master_def: + MASTER_HOST_SYM EQ TEXT_STRING_sys + { + Lex->mi.host = $3.str; + } + | + MASTER_USER_SYM EQ TEXT_STRING_sys + { + Lex->mi.user = $3.str; + } + | + MASTER_PASSWORD_SYM EQ TEXT_STRING_sys + { + Lex->mi.password = $3.str; + } + | + MASTER_PORT_SYM EQ ULONG_NUM + { + Lex->mi.port = $3; + } + | + MASTER_CONNECT_RETRY_SYM EQ ULONG_NUM + { + Lex->mi.connect_retry = $3; + } + | MASTER_SSL_SYM EQ ULONG_NUM + { + Lex->mi.ssl= $3 ? + LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE; + } + | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_ca= $3.str; + } + | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_capath= $3.str; + } + | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_cert= $3.str; + } + | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_cipher= $3.str; + } + | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_key= $3.str; + } + | + master_file_def + ; + +master_file_def: + MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys + { + Lex->mi.log_file_name = $3.str; + } + | MASTER_LOG_POS_SYM EQ ulonglong_num + { + Lex->mi.pos = $3; + /* + If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it + instead of causing subsequent errors. + We need to do it in this file, because only there we know that + MASTER_LOG_POS has been explicitely specified. On the contrary + in change_master() (sql_repl.cc) we cannot distinguish between 0 + (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified), + whereas we want to distinguish (specified 0 means "read the binlog + from 0" (4 in fact), unspecified means "don't change the position + (keep the preceding value)"). + */ + Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos); + } + | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys + { + Lex->mi.relay_log_name = $3.str; + } + | RELAY_LOG_POS_SYM EQ ULONG_NUM + { + Lex->mi.relay_log_pos = $3; + /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */ + Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos); + } + ; + +/* create a table */ + +create: + CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident + { + THD *thd= YYTHD; + LEX *lex=Lex; + lex->sql_command= SQLCOM_CREATE_TABLE; + if (!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + (using_update_log ? + TL_READ_NO_INSERT: + TL_READ))) + YYABORT; + lex->create_list.empty(); + lex->key_list.empty(); + lex->col_list.empty(); + lex->change=NullS; + bzero((char*) &lex->create_info,sizeof(lex->create_info)); + lex->create_info.options=$2 | $4; + lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type; + lex->create_info.default_table_charset= NULL; + lex->name=0; + } + create2 + { Lex->current_select= &Lex->select_lex; } + | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_CREATE_INDEX; + if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, + TL_OPTION_UPDATING)) + YYABORT; + lex->create_list.empty(); + lex->key_list.empty(); + lex->col_list.empty(); + lex->change=NullS; + } + '(' key_list ')' + { + LEX *lex=Lex; + + lex->key_list.push_back(new Key($2,$4.str, $5, 0, lex->col_list)); + lex->col_list.empty(); + } + | CREATE DATABASE opt_if_not_exists ident + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + } + opt_create_database_options + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_CREATE_DB; + lex->name=$4.str; + lex->create_info.options=$3; + } + | CREATE udf_func_type FUNCTION_SYM sp_name + { + LEX *lex=Lex; + lex->spname= $4; + lex->udf.type= $2; + } + create_function_tail + {} + | CREATE PROCEDURE sp_name + { + LEX *lex= Lex; + sp_head *sp; + + if (lex->sphead) + { + net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "PROCEDURE"); + YYABORT; + } + /* Order is important here: new - reset - init */ + sp= new sp_head(); + sp->reset_thd_mem_root(YYTHD); + sp->init(lex); + + sp->m_type= TYPE_ENUM_PROCEDURE; + lex->sphead= sp; + /* + * We have to turn of CLIENT_MULTI_QUERIES while parsing a + * stored procedure, otherwise yylex will chop it into pieces + * at each ';'. + */ + sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); + } + '(' + { + LEX *lex= Lex; + + lex->sphead->m_param_begin= lex->tok_start+1; + } + sp_pdparam_list + ')' + { + LEX *lex= Lex; + + lex->sphead->m_param_end= lex->tok_start; + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_c_chistics + { + LEX *lex= Lex; + + lex->sphead->m_chistics= &lex->sp_chistics; + lex->sphead->m_body_begin= lex->tok_start; + } + sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + if (sp->check_backpatch(YYTHD)) + YYABORT; + sp->init_strings(YYTHD, lex, $3); + lex->sql_command= SQLCOM_CREATE_PROCEDURE; + /* Restore flag if it was cleared above */ + if (sp->m_old_cmq) + YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; + sp->restore_thd_mem_root(YYTHD); + } + | CREATE or_replace algorithm VIEW_SYM table_ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->sql_command= SQLCOM_CREATE_VIEW; + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + /* first table in list is target VIEW name */ + if (!lex->select_lex.add_table_to_list(thd, $5, NULL, 0)) + YYABORT; + } + opt_view_list AS select_init check_option + {} + | CREATE TRIGGER_SYM ident trg_action_time trg_event + ON table_ident FOR_SYM EACH_SYM ROW_SYM + { + LEX *lex= Lex; + sp_head *sp; + + if (lex->sphead) + { + net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "TRIGGER"); + YYABORT; + } + + sp= new sp_head(); + sp->reset_thd_mem_root(YYTHD); + sp->init(lex); + + sp->m_type= TYPE_ENUM_TRIGGER; + lex->sphead= sp; + /* + We have to turn of CLIENT_MULTI_QUERIES while parsing a + stored procedure, otherwise yylex will chop it into pieces + at each ';'. + */ + sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; + + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + lex->sphead->m_chistics= &lex->sp_chistics; + lex->sphead->m_body_begin= lex->tok_start; + } + sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + lex->sql_command= SQLCOM_CREATE_TRIGGER; + sp->init_strings(YYTHD, lex, NULL); + /* Restore flag if it was cleared above */ + if (sp->m_old_cmq) + YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; + sp->restore_thd_mem_root(YYTHD); + + lex->name_and_length= $3; + + /* + We have to do it after parsing trigger body, because some of + sp_proc_stmt alternatives are not saving/restoring LEX, so + lex->query_tables can be wiped out. + + QQ: What are other consequences of this? + + QQ: Could we loosen lock type in certain cases ? + */ + if (!lex->select_lex.add_table_to_list(YYTHD, $7, + (LEX_STRING*) 0, + TL_OPTION_UPDATING, + TL_WRITE)) + YYABORT; + } + ; + +sp_name: + IDENT_sys '.' IDENT_sys + { + $$= new sp_name($1, $3); + $$->init_qname(YYTHD); + } + | IDENT_sys + { + $$= sp_name_current_db_new(YYTHD, $1); + } + ; + +create_function_tail: + RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_CREATE_FUNCTION; + lex->udf.name = lex->spname->m_name; + lex->udf.returns=(Item_result) $2; + lex->udf.dl=$4.str; + } + | '(' + { + LEX *lex= Lex; + sp_head *sp; + + if (lex->sphead) + { + net_printf(YYTHD, ER_SP_NO_RECURSIVE_CREATE, "FUNCTION"); + YYABORT; + } + /* Order is important here: new - reset - init */ + sp= new sp_head(); + sp->reset_thd_mem_root(YYTHD); + sp->init(lex); + + sp->m_type= TYPE_ENUM_FUNCTION; + lex->sphead= sp; + /* + * We have to turn of CLIENT_MULTI_QUERIES while parsing a + * stored procedure, otherwise yylex will chop it into pieces + * at each ';'. + */ + sp->m_old_cmq= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; + lex->sphead->m_param_begin= lex->tok_start+1; + } + sp_fdparam_list ')' + { + LEX *lex= Lex; + + lex->sphead->m_param_end= lex->tok_start; + } + RETURNS_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + sp->m_returns_begin= lex->tok_start; + sp->m_returns_cs= lex->charset= NULL; + } + type + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + sp->m_returns_end= lex->tok_start; + sp->m_returns= (enum enum_field_types)$8; + sp->m_returns_cs= lex->charset; + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_c_chistics + { + LEX *lex= Lex; + + lex->sphead->m_chistics= &lex->sp_chistics; + lex->sphead->m_body_begin= lex->tok_start; + } + sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + if (sp->check_backpatch(YYTHD)) + YYABORT; + lex->sql_command= SQLCOM_CREATE_SPFUNCTION; + sp->init_strings(YYTHD, lex, lex->spname); + /* Restore flag if it was cleared above */ + if (sp->m_old_cmq) + YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; + sp->restore_thd_mem_root(YYTHD); + } + ; + +sp_a_chistics: + /* Empty */ {} + | sp_a_chistics sp_chistic {} + ; + +sp_c_chistics: + /* Empty */ {} + | sp_c_chistics sp_c_chistic {} + ; + +/* Characteristics for both create and alter */ +sp_chistic: + COMMENT_SYM TEXT_STRING_sys + { Lex->sp_chistics.comment= $2; } + | LANGUAGE_SYM SQL_SYM + { /* Just parse it, we only have one language for now. */ } + | NO_SYM SQL_SYM + { Lex->sp_chistics.daccess= SP_NO_SQL; } + | CONTAINS_SYM SQL_SYM + { Lex->sp_chistics.daccess= SP_CONTAINS_SQL; } + | READS_SYM SQL_SYM DATA_SYM + { Lex->sp_chistics.daccess= SP_READS_SQL_DATA; } + | MODIFIES_SYM SQL_SYM DATA_SYM + { Lex->sp_chistics.daccess= SP_MODIFIES_SQL_DATA; } + | sp_suid + { } + ; + +/* Create characteristics */ +sp_c_chistic: + sp_chistic { } + | DETERMINISTIC_SYM { Lex->sp_chistics.detistic= TRUE; } + | NOT DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; } + ; + +sp_suid: + SQL_SYM SECURITY_SYM DEFINER_SYM + { + Lex->sp_chistics.suid= SP_IS_SUID; + } + | SQL_SYM SECURITY_SYM INVOKER_SYM + { + Lex->sp_chistics.suid= SP_IS_NOT_SUID; + } + ; + +call: + CALL_SYM sp_name + { + LEX *lex = Lex; + + lex->sql_command= SQLCOM_CALL; + lex->spname= $2; + lex->value_list.empty(); + } + '(' sp_cparam_list ')' {} + ; + +/* CALL parameters */ +sp_cparam_list: + /* Empty */ + | sp_cparams + ; + +sp_cparams: + sp_cparams ',' expr + { + Lex->value_list.push_back($3); + } + | expr + { + Lex->value_list.push_back($1); + } + ; + +/* Stored FUNCTION parameter declaration list */ +sp_fdparam_list: + /* Empty */ + | sp_fdparams + ; + +sp_fdparams: + sp_fdparams ',' sp_fdparam + | sp_fdparam + ; + +sp_fdparam: + ident type + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$1, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_PARAM, $1.str); + YYABORT; + } + spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); + } + ; + +/* Stored PROCEDURE parameter declaration list */ +sp_pdparam_list: + /* Empty */ + | sp_pdparams + ; + +sp_pdparams: + sp_pdparams ',' sp_pdparam + | sp_pdparam + ; + +sp_pdparam: + sp_opt_inout ident type + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$2, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_PARAM, $2.str); + YYABORT; + } + spc->push_pvar(&$2, (enum enum_field_types)$3, + (sp_param_mode_t)$1); + } + ; + +sp_opt_inout: + /* Empty */ { $$= sp_param_in; } + | IN_SYM { $$= sp_param_in; } + | OUT_SYM { $$= sp_param_out; } + | INOUT_SYM { $$= sp_param_inout; } + ; + +sp_proc_stmts: + /* Empty */ {} + | sp_proc_stmts { Lex->query_tables= 0; } sp_proc_stmt ';' + ; + +sp_proc_stmts1: + sp_proc_stmt ';' {} + | sp_proc_stmts1 { Lex->query_tables= 0; } sp_proc_stmt ';' + ; + +sp_decls: + /* Empty */ + { + $$.vars= $$.conds= $$.hndlrs= $$.curs= 0; + } + | sp_decls sp_decl ';' + { + /* We check for declarations out of (standard) order this way + because letting the grammar rules reflect it caused tricky + shift/reduce conflicts with the wrong result. (And we get + better error handling this way.) */ + if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs)) + { /* Variable or condition following cursor or handler */ + send_error(YYTHD, ER_SP_VARCOND_AFTER_CURSHNDLR); + YYABORT; + } + if ($2.curs && $1.hndlrs) + { /* Cursor following handler */ + send_error(YYTHD, ER_SP_CURSOR_AFTER_HANDLER); + YYABORT; + } + $$.vars= $1.vars + $2.vars; + $$.conds= $1.conds + $2.conds; + $$.hndlrs= $1.hndlrs + $2.hndlrs; + $$.curs= $1.curs + $2.curs; + } + ; + +sp_decl: + DECLARE_SYM sp_decl_idents type sp_opt_default + { + LEX *lex= Lex; + sp_pcontext *ctx= lex->spcont; + uint max= ctx->context_pvars(); + enum enum_field_types type= (enum enum_field_types)$3; + Item *it= $4; + + for (uint i = max-$2 ; i < max ; i++) + { + ctx->set_type(i, type); + if (! it) + ctx->set_isset(i, FALSE); + else + { + sp_instr_set *in= new sp_instr_set(lex->sphead->instructions(), + ctx, + ctx->pvar_context2index(i), + it, type); + + in->tables= lex->query_tables; + lex->query_tables= 0; + lex->sphead->add_instr(in); + ctx->set_isset(i, TRUE); + ctx->set_default(i, it); + } + } + $$.vars= $2; + $$.conds= $$.hndlrs= $$.curs= 0; + } + | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_cond(&$2, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_COND, $2.str); + YYABORT; + } + YYTHD->lex->spcont->push_cond(&$2, $5); + $$.vars= $$.hndlrs= $$.curs= 0; + $$.conds= 1; + } + | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_instr_hpush_jump *i= + new sp_instr_hpush_jump(sp->instructions(), ctx, $2, + ctx->current_pvars()); + + sp->add_instr(i); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + ctx->add_handler(); + sp->m_in_handler= TRUE; + } + sp_hcond_list sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_label_t *hlab= lex->spcont->pop_label(); /* After this hdlr */ + sp_instr_hreturn *i; + + if ($2 == SP_HANDLER_CONTINUE) + { + i= new sp_instr_hreturn(sp->instructions(), ctx, + ctx->current_pvars()); + sp->add_instr(i); + } + else + { /* EXIT or UNDO handler, just jump to the end of the block */ + i= new sp_instr_hreturn(sp->instructions(), ctx, 0); + + sp->add_instr(i); + sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */ + } + lex->sphead->backpatch(hlab); + sp->m_in_handler= FALSE; + $$.vars= $$.conds= $$.curs= 0; + $$.hndlrs= $6; + } + | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + uint offp; + sp_instr_cpush *i; + + if (ctx->find_cursor(&$2, &offp, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_CURS, $2.str); + delete $5; + YYABORT; + } + i= new sp_instr_cpush(sp->instructions(), ctx, $5); + sp->add_instr(i); + ctx->push_cursor(&$2); + $$.vars= $$.conds= $$.hndlrs= 0; + $$.curs= 1; + } + ; + +sp_cursor_stmt: + { + Lex->sphead->reset_lex(YYTHD); + + /* We use statement here just be able to get a better + error message. Using 'select' works too, but will then + result in a generic "syntax error" if a non-select + statement is given. */ + } + statement + { + LEX *lex= Lex; + + if (lex->sql_command != SQLCOM_SELECT) + { + send_error(YYTHD, ER_SP_BAD_CURSOR_QUERY); + YYABORT; + } + if (lex->result) + { + send_error(YYTHD, ER_SP_BAD_CURSOR_SELECT); + YYABORT; + } + lex->sp_lex_in_use= TRUE; + $$= lex; + lex->sphead->restore_lex(YYTHD); + } + ; + +sp_handler_type: + EXIT_SYM { $$= SP_HANDLER_EXIT; } + | CONTINUE_SYM { $$= SP_HANDLER_CONTINUE; } +/* | UNDO_SYM { QQ No yet } */ + ; + +sp_hcond_list: + sp_hcond + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($1); + $$= 1; + } + | sp_hcond_list ',' sp_hcond + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($3); + $$= $1 + 1; + } + ; + +sp_cond: + ULONG_NUM + { /* mysql errno */ + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::number; + $$->mysqlerr= $1; + } + | SQLSTATE_SYM opt_value TEXT_STRING_literal + { /* SQLSTATE */ + uint len= ($3.length < sizeof($$->sqlstate)-1 ? + $3.length : sizeof($$->sqlstate)-1); + + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::state; + memcpy($$->sqlstate, $3.str, len); + $$->sqlstate[len]= '\0'; + } + ; + +opt_value: + /* Empty */ {} + | VALUE_SYM {} + ; + +sp_hcond: + sp_cond + { + $$= $1; + } + | ident /* CONDITION name */ + { + $$= Lex->spcont->find_cond(&$1); + if ($$ == NULL) + { + net_printf(YYTHD, ER_SP_COND_MISMATCH, $1.str); + YYABORT; + } + } + | SQLWARNING_SYM /* SQLSTATEs 01??? */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::warning; + } + | NOT FOUND_SYM /* SQLSTATEs 02??? */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::notfound; + } + | SQLEXCEPTION_SYM /* All other SQLSTATEs */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::exception; + } + ; + +sp_decl_idents: + ident + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$1, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_VAR, $1.str); + YYABORT; + } + spc->push_pvar(&$1, (enum_field_types)0, sp_param_in); + $$= 1; + } + | sp_decl_idents ',' ident + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_pvar(&$3, TRUE)) + { + net_printf(YYTHD, ER_SP_DUP_VAR, $3.str); + YYABORT; + } + spc->push_pvar(&$3, (enum_field_types)0, sp_param_in); + $$= $1 + 1; + } + ; + +sp_opt_default: + /* Empty */ { $$ = NULL; } + | DEFAULT expr { $$ = $2; } + ; + +sp_proc_stmt: + { + LEX *lex= Lex; + + lex->sphead->reset_lex(YYTHD); + lex->sphead->m_tmp_query= lex->tok_start; + } + statement + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + if ((lex->sql_command == SQLCOM_SELECT && !lex->result) || + sp_multi_results_command(lex->sql_command)) + { + /* We maybe have one or more SELECT without INTO */ + sp->m_multi_results= TRUE; + } + if (lex->sql_command == SQLCOM_CHANGE_DB) + { /* "USE db" doesn't work in a procedure */ + send_error(YYTHD, ER_SP_NO_USE); + YYABORT; + } + /* Don't add an instruction for empty SET statements. + ** (This happens if the SET only contained local variables, + ** which get their set instructions generated separately.) + */ + if (lex->sql_command != SQLCOM_SET_OPTION || + ! lex->var_list.is_empty()) + { + /* + Currently we can't handle queries inside a FUNCTION or + TRIGGER, because of the way table locking works. This is + unfortunate, and limits the usefulness of functions and + especially triggers a tremendously, but it's nothing we + can do about this at the moment. + */ + if (sp->m_type != TYPE_ENUM_PROCEDURE) + { + send_error(YYTHD, ER_SP_BADSTATEMENT); + YYABORT; + } + else + { + sp_instr_stmt *i=new sp_instr_stmt(sp->instructions(), + lex->spcont); + + /* Extract the query statement from the tokenizer: + The end is either lex->tok_end or tok->ptr. */ + if (lex->ptr - lex->tok_end > 1) + i->m_query.length= lex->ptr - sp->m_tmp_query; + else + i->m_query.length= lex->tok_end - sp->m_tmp_query; + i->m_query.str= strmake_root(YYTHD->mem_root, + (char *)sp->m_tmp_query, + i->m_query.length); + i->set_lex(lex); + sp->add_instr(i); + lex->sp_lex_in_use= TRUE; + } + } + sp->restore_lex(YYTHD); + } + | RETURN_SYM expr + { + LEX *lex= Lex; + + if (lex->sphead->m_type == TYPE_ENUM_PROCEDURE) + { + send_error(YYTHD, ER_SP_BADRETURN); + YYABORT; + } + else + { + sp_instr_freturn *i; + + if ($2->type() == Item::SUBSELECT_ITEM) + { /* QQ For now, just disallow subselects as values */ + send_error(lex->thd, ER_SP_BADSTATEMENT); + YYABORT; + } + i= new sp_instr_freturn(lex->sphead->instructions(), + lex->spcont, + $2, lex->sphead->m_returns); + lex->sphead->add_instr(i); + lex->sphead->m_has_return= TRUE; + } + } + | IF sp_if END IF {} + | CASE_SYM WHEN_SYM + { + Lex->sphead->m_simple_case= FALSE; + } + sp_case END CASE_SYM {} + | CASE_SYM expr WHEN_SYM + { + /* We "fake" this by using an anonymous variable which we + set to the expression. Note that all WHENs are evaluate + at the same frame level, so we then know that it's the + top-most variable in the frame. */ + LEX *lex= Lex; + uint offset= lex->spcont->current_pvars(); + sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(), + lex->spcont, + offset, $2, MYSQL_TYPE_STRING); + LEX_STRING dummy; + + dummy.str= (char *)""; + dummy.length= 0; + lex->spcont->push_pvar(&dummy, MYSQL_TYPE_STRING, sp_param_in); + i->tables= lex->query_tables; + lex->query_tables= 0; + lex->sphead->add_instr(i); + lex->sphead->m_simple_case= TRUE; + } + sp_case END CASE_SYM + { + Lex->spcont->pop_pvar(); + } + | sp_labeled_control + {} + | { /* Unlabeled controls get a secret label. */ + LEX *lex= Lex; + + lex->spcont->push_label((char *)"", lex->sphead->instructions()); + } + sp_unlabeled_control + { + LEX *lex= Lex; + + lex->sphead->backpatch(lex->spcont->pop_label()); + } + | LEAVE_SYM IDENT + { + LEX *lex= Lex; + sp_head *sp = lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($2.str); + + if (! lab) + { + net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "LEAVE", $2.str); + YYABORT; + } + else + { + uint ip= sp->instructions(); + sp_instr_jump *i; + sp_instr_hpop *ih; + sp_instr_cpop *ic; + + ih= new sp_instr_hpop(ip++, ctx, 0); + sp->push_backpatch(ih, lab); + sp->add_instr(ih); + ic= new sp_instr_cpop(ip++, ctx, 0); + sp->push_backpatch(ic, lab); + sp->add_instr(ic); + i= new sp_instr_jump(ip, ctx); + sp->push_backpatch(i, lab); /* Jumping forward */ + sp->add_instr(i); + } + } + | ITERATE_SYM IDENT + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($2.str); + + if (! lab || lab->type != SP_LAB_ITER) + { + net_printf(YYTHD, ER_SP_LILABEL_MISMATCH, "ITERATE", $2.str); + YYABORT; + } + else + { + sp_instr_jump *i; + uint ip= sp->instructions(); + uint n; + + n= ctx->diff_handlers(lab->ctx); + if (n) + sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); + n= ctx->diff_cursors(lab->ctx); + if (n) + sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); + i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ + sp->add_instr(i); + } + } + | LABEL_SYM IDENT + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($2.str); + + if (lab) + { + net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $2.str); + YYABORT; + } + else + { + lab= ctx->push_label($2.str, sp->instructions()); + lab->type= SP_LAB_GOTO; + lab->ctx= ctx; + sp->backpatch(lab); + } + } + | GOTO_SYM IDENT + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + uint ip= lex->sphead->instructions(); + sp_label_t *lab; + sp_instr_jump *i; + sp_instr_hpop *ih; + sp_instr_cpop *ic; + + if (sp->m_in_handler) + { + send_error(lex->thd, ER_SP_GOTO_IN_HNDLR); + YYABORT; + } + lab= ctx->find_label($2.str); + if (! lab) + { + lab= (sp_label_t *)YYTHD->alloc(sizeof(sp_label_t)); + lab->name= $2.str; + lab->ip= 0; + lab->type= SP_LAB_REF; + lab->ctx= ctx; + + ih= new sp_instr_hpop(ip++, ctx, 0); + sp->push_backpatch(ih, lab); + sp->add_instr(ih); + ic= new sp_instr_cpop(ip++, ctx, 0); + sp->add_instr(ic); + sp->push_backpatch(ic, lab); + i= new sp_instr_jump(ip, ctx); + sp->push_backpatch(i, lab); /* Jumping forward */ + sp->add_instr(i); + } + else + { + uint n; + + n= ctx->diff_handlers(lab->ctx); + if (n) + { + ih= new sp_instr_hpop(ip++, ctx, n); + sp->add_instr(ih); + } + n= ctx->diff_cursors(lab->ctx); + if (n) + { + ic= new sp_instr_cpop(ip++, ctx, n); + sp->add_instr(ic); + } + i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ + sp->add_instr(i); + } + } + | OPEN_SYM ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_copen *i; + + if (! lex->spcont->find_cursor(&$2, &offset)) + { + net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + YYABORT; + } + i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); + sp->add_instr(i); + } + | FETCH_SYM sp_opt_fetch_noise ident INTO + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_cfetch *i; + + if (! lex->spcont->find_cursor(&$3, &offset)) + { + net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $3.str); + YYABORT; + } + i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); + sp->add_instr(i); + } + sp_fetch_list + { } + | CLOSE_SYM ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_cclose *i; + + if (! lex->spcont->find_cursor(&$2, &offset)) + { + net_printf(YYTHD, ER_SP_CURSOR_MISMATCH, $2.str); + YYABORT; + } + i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); + sp->add_instr(i); + } + ; + +sp_opt_fetch_noise: + /* Empty */ + | NEXT_SYM FROM + | FROM + ; + +sp_fetch_list: + ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + if (!spc || !(spv = spc->find_pvar(&$1))) + { + net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str); + YYABORT; + } + else + { + /* An SP local variable */ + sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); + + i->add_to_varlist(spv); + spv->isset= TRUE; + } + } + | + sp_fetch_list ',' ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + if (!spc || !(spv = spc->find_pvar(&$3))) + { + net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $3.str); + YYABORT; + } + else + { + /* An SP local variable */ + sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); + + i->add_to_varlist(spv); + spv->isset= TRUE; + } + } + ; + +sp_if: + expr THEN_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx, $1); + + i->tables= lex->query_tables; + lex->query_tables= 0; + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + sp->add_instr(i); + } + sp_proc_stmts1 + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump *i = new sp_instr_jump(ip, ctx); + + sp->add_instr(i); + sp->backpatch(ctx->pop_label()); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + } + sp_elseifs + { + LEX *lex= Lex; + + lex->sphead->backpatch(lex->spcont->pop_label()); + } + ; + +sp_elseifs: + /* Empty */ + | ELSEIF_SYM sp_if + | ELSE sp_proc_stmts1 + ; + +sp_case: + expr THEN_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i; + + if (! sp->m_simple_case) + i= new sp_instr_jump_if_not(ip, ctx, $1); + else + { /* Simple case: = */ + LEX_STRING ivar; + + ivar.str= (char *)"_tmp_"; + ivar.length= 5; + Item *var= (Item*) new Item_splocal(ivar, + ctx->current_pvars()-1); + Item *expr= new Item_func_eq(var, $1); + + i= new sp_instr_jump_if_not(ip, ctx, expr); + lex->variables_used= 1; + } + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + i->tables= lex->query_tables; + lex->query_tables= 0; + sp->add_instr(i); + } + sp_proc_stmts1 + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump *i = new sp_instr_jump(ip, ctx); + + sp->add_instr(i); + sp->backpatch(ctx->pop_label()); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + } + sp_whens + { + LEX *lex= Lex; + + lex->sphead->backpatch(lex->spcont->pop_label()); + } + ; -master_file_def: - MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys - { - Lex->mi.log_file_name = $3.str; - } - | MASTER_LOG_POS_SYM EQ ulonglong_num - { - Lex->mi.pos = $3; - /* - If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it - instead of causing subsequent errors. - We need to do it in this file, because only there we know that - MASTER_LOG_POS has been explicitely specified. On the contrary - in change_master() (sql_repl.cc) we cannot distinguish between 0 - (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified), - whereas we want to distinguish (specified 0 means "read the binlog - from 0" (4 in fact), unspecified means "don't change the position - (keep the preceding value)"). - */ - Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos); - } - | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys - { - Lex->mi.relay_log_name = $3.str; - } - | RELAY_LOG_POS_SYM EQ ULONG_NUM - { - Lex->mi.relay_log_pos = $3; - /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */ - Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos); - } - ; +sp_whens: + /* Empty */ + { + sp_head *sp= Lex->sphead; + uint ip= sp->instructions(); + sp_instr_error *i= new sp_instr_error(ip, Lex->spcont, + ER_SP_CASE_NOT_FOUND); -/* create a table */ + sp->add_instr(i); + } + | ELSE sp_proc_stmts1 {} + | WHEN_SYM sp_case {} + ; -create: - CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident - { - THD *thd= YYTHD; - LEX *lex=Lex; - lex->sql_command= SQLCOM_CREATE_TABLE; - if (!lex->select_lex.add_table_to_list(thd, $5, NULL, - TL_OPTION_UPDATING, - (using_update_log ? - TL_READ_NO_INSERT: - TL_READ))) - YYABORT; - lex->create_list.empty(); - lex->key_list.empty(); - lex->col_list.empty(); - lex->change=NullS; - bzero((char*) &lex->create_info,sizeof(lex->create_info)); - lex->create_info.options=$2 | $4; - lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type; - lex->create_info.default_table_charset= NULL; - lex->name=0; - } - create2 - { Lex->current_select= &Lex->select_lex; } - | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident +sp_labeled_control: + IDENT ':' { - LEX *lex=Lex; - lex->sql_command= SQLCOM_CREATE_INDEX; - if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, - TL_OPTION_UPDATING)) + LEX *lex= Lex; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($1.str); + + if (lab) + { + net_printf(YYTHD, ER_SP_LABEL_REDEFINE, $1.str); YYABORT; - lex->create_list.empty(); - lex->key_list.empty(); - lex->col_list.empty(); - lex->change=NullS; + } + else + { + lab= lex->spcont->push_label($1.str, + lex->sphead->instructions()); + lab->type= SP_LAB_ITER; + } } - '(' key_list ')' + sp_unlabeled_control sp_opt_label { - LEX *lex=Lex; + LEX *lex= Lex; - lex->key_list.push_back(new Key($2,$4.str, $5, 0, lex->col_list)); - lex->col_list.empty(); + if ($5.str) + { + sp_label_t *lab= lex->spcont->find_label($5.str); + + if (!lab || + my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) + { + net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); + YYABORT; + } + } + lex->sphead->backpatch(lex->spcont->pop_label()); } - | CREATE DATABASE opt_if_not_exists ident + ; + +sp_opt_label: + /* Empty */ + { $$.str= NULL; $$.length= 0; } + | IDENT + { $$= $1; } + ; + +sp_unlabeled_control: + BEGIN_SYM + { /* QQ This is just a dummy for grouping declarations and statements + together. No [[NOT] ATOMIC] yet, and we need to figure out how + make it coexist with the existing BEGIN COMMIT/ROLLBACK. */ + LEX *lex= Lex; + sp_label_t *lab= lex->spcont->last_label(); + + lab->type= SP_LAB_BEGIN; + lex->spcont= lex->spcont->push_context(); + } + sp_decls + sp_proc_stmts + END { - Lex->create_info.default_table_charset= NULL; - Lex->create_info.used_fields= 0; - } - opt_create_database_options + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + + sp->backpatch(ctx->last_label()); /* We always have a label */ + if ($3.hndlrs) + sp->add_instr(new sp_instr_hpop(sp->instructions(), ctx, + $3.hndlrs)); + if ($3.curs) + sp->add_instr(new sp_instr_cpop(sp->instructions(), ctx, + $3.curs)); + lex->spcont= ctx->pop_context(); + } + | LOOP_SYM + sp_proc_stmts1 END LOOP_SYM { - LEX *lex=Lex; - lex->sql_command=SQLCOM_CREATE_DB; - lex->name=$4.str; - lex->create_info.options=$3; + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); + + lex->sphead->add_instr(i); } - | CREATE udf_func_type UDF_SYM IDENT_sys + | WHILE_SYM expr DO_SYM { - LEX *lex=Lex; - lex->sql_command = SQLCOM_CREATE_FUNCTION; - lex->udf.name = $4; - lex->udf.type= $2; + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, + $2); + + /* Jumping forward */ + sp->push_backpatch(i, lex->spcont->last_label()); + i->tables= lex->query_tables; + lex->query_tables= 0; + sp->add_instr(i); } - UDF_RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys + sp_proc_stmts1 END WHILE_SYM { - LEX *lex=Lex; - lex->udf.returns=(Item_result) $7; - lex->udf.dl=$9.str; + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); + + lex->sphead->add_instr(i); + } + | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM expr END REPEAT_SYM + { + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, + $4, lab->ip); + + i->tables= lex->query_tables; + lex->query_tables= 0; + lex->sphead->add_instr(i); } + ; + +trg_action_time: + BEFORE_SYM + { Lex->trg_chistics.action_time= TRG_ACTION_BEFORE; } + | AFTER_SYM + { Lex->trg_chistics.action_time= TRG_ACTION_AFTER; } + ; + +trg_event: + INSERT + { Lex->trg_chistics.event= TRG_EVENT_INSERT; } + | UPDATE_SYM + { Lex->trg_chistics.event= TRG_EVENT_UPDATE; } + | DELETE_SYM + { Lex->trg_chistics.event= TRG_EVENT_DELETE; } ; create2: @@ -1117,6 +2440,10 @@ create_select: lex->sql_command= SQLCOM_INSERT_SELECT; else if (lex->sql_command == SQLCOM_REPLACE) lex->sql_command= SQLCOM_REPLACE_SELECT; + /* + The following work only with the local list, the global list + is created correctly in this case + */ lex->current_select->table_list.save_and_clear(&lex->save_list); mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; @@ -1126,7 +2453,13 @@ create_select: Select->parsing_place= NO_MATTER; } opt_select_from - { Lex->current_select->table_list.push_front(&Lex->save_list); } + { + /* + The following work only with the local list, the global list + is created correctly in this case + */ + Lex->current_select->table_list.push_front(&Lex->save_list); + } ; opt_as: @@ -1174,19 +2507,19 @@ create_table_options: | create_table_option ',' create_table_options; create_table_option: - ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; } - | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); } + ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; } + | TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; } | MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;} | MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;} | AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} - | PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; } - | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; } + | PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; } + | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; } | AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;} | PACK_KEYS_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} | PACK_KEYS_SYM opt_equal DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} - | CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; } - | DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; } - | ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; } + | CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; } + | DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; } + | ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; } | RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} | RAID_CHUNKS opt_equal ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} | RAID_CHUNKSIZE opt_equal ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} @@ -1197,18 +2530,20 @@ create_table_option: TABLE_LIST *table_list= lex->select_lex.get_table_list(); lex->create_info.merge_list= lex->select_lex.table_list; lex->create_info.merge_list.elements--; - lex->create_info.merge_list.first= (byte*) (table_list->next); + lex->create_info.merge_list.first= + (byte*) (table_list->next_local); lex->select_lex.table_list.elements=1; - lex->select_lex.table_list.next= (byte**) &(table_list->next); - table_list->next=0; + lex->select_lex.table_list.next= + (byte**) &(table_list->next_local); + table_list->next_local= 0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } | default_charset | default_collation | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} - | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys - { Lex->create_info.data_file_name= $4.str; } - | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; }; + | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR; } + | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR; } + ; default_charset: opt_default charset opt_equal charset_name_or_default @@ -1823,14 +3158,12 @@ key_part: | ident '(' NUM ')' { int key_part_len= atoi($3.str); -#if MYSQL_VERSION_ID < 50000 if (!key_part_len) { my_printf_error(ER_UNKNOWN_ERROR, "Key part '%s' length cannot be 0", MYF(0), $1.str); } -#endif $$=new key_part_spec($1.str,(uint) key_part_len); }; @@ -1869,8 +3202,7 @@ alter: lex->create_info.db_type= DB_TYPE_DEFAULT; lex->create_info.default_table_charset= NULL; lex->create_info.row_type= ROW_TYPE_NOT_USED; - lex->alter_info.reset(); - lex->alter_info.is_simple= 1; + lex->alter_info.reset(); lex->alter_info.flags= 0; } alter_list @@ -1885,8 +3217,48 @@ alter: LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; - }; + } + | ALTER PROCEDURE sp_name + { + LEX *lex= Lex; + + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_a_chistics + { + THD *thd= YYTHD; + LEX *lex=Lex; + + lex->sql_command= SQLCOM_ALTER_PROCEDURE; + lex->spname= $3; + } + | ALTER FUNCTION_SYM sp_name + { + LEX *lex= Lex; + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_a_chistics + { + THD *thd= YYTHD; + LEX *lex=Lex; + + lex->sql_command= SQLCOM_ALTER_FUNCTION; + lex->spname= $3; + } + | ALTER algorithm VIEW_SYM table_ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->sql_command= SQLCOM_CREATE_VIEW; + lex->create_view_mode= VIEW_ALTER; + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + /* first table in list is target VIEW name */ + lex->select_lex.add_table_to_list(thd, $4, NULL, 0); + } + opt_view_list AS select_init check_option + {} + ; alter_list: | DISCARD TABLESPACE { Lex->alter_info.tablespace_op= DISCARD_TABLESPACE; } @@ -1895,27 +3267,27 @@ alter_list: | alter_list ',' alter_list_item; add_column: - ADD opt_column + ADD opt_column { LEX *lex=Lex; - lex->change=0; - lex->alter_info.flags|= ALTER_ADD_COLUMN; + lex->change=0; + lex->alter_info.flags|= ALTER_ADD_COLUMN; }; alter_list_item: - add_column column_def opt_place { Lex->alter_info.is_simple= 0; } - | ADD key_def - { - LEX *lex=Lex; - lex->alter_info.is_simple= 0; - lex->alter_info.flags|= ALTER_ADD_INDEX; + add_column column_def opt_place { } + | ADD key_def + { + Lex->alter_info.flags|= ALTER_ADD_INDEX; } - | add_column '(' field_list ')' { Lex->alter_info.is_simple= 0; } + | add_column '(' field_list ')' + { + Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX; + } | CHANGE opt_column field_ident { LEX *lex=Lex; - lex->change= $3.str; - lex->alter_info.is_simple= 0; + lex->change= $3.str; lex->alter_info.flags|= ALTER_CHANGE_COLUMN; } field_spec opt_place @@ -1926,7 +3298,6 @@ alter_list_item: lex->default_value= lex->on_update_value= 0; lex->comment=0; lex->charset= NULL; - lex->alter_info.is_simple= 0; lex->alter_info.flags|= ALTER_CHANGE_COLUMN; } type opt_attribute @@ -1946,17 +3317,18 @@ alter_list_item: { LEX *lex=Lex; lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::COLUMN, - $3.str)); - lex->alter_info.is_simple= 0; + $3.str)); lex->alter_info.flags|= ALTER_DROP_COLUMN; } - | DROP FOREIGN KEY_SYM opt_ident { Lex->alter_info.is_simple= 0; } + | DROP FOREIGN KEY_SYM opt_ident + { + Lex->alter_info.flags|= ALTER_DROP_INDEX; + } | DROP PRIMARY_SYM KEY_SYM { LEX *lex=Lex; lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, primary_key_name)); - lex->alter_info.is_simple= 0; lex->alter_info.flags|= ALTER_DROP_INDEX; } | DROP key_or_index field_ident @@ -1964,25 +3336,32 @@ alter_list_item: LEX *lex=Lex; lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, $3.str)); - lex->alter_info.is_simple= 0; lex->alter_info.flags|= ALTER_DROP_INDEX; } - | DISABLE_SYM KEYS { Lex->alter_info.keys_onoff= DISABLE; } - | ENABLE_SYM KEYS { Lex->alter_info.keys_onoff= ENABLE; } + | DISABLE_SYM KEYS + { + LEX *lex=Lex; + lex->alter_info.keys_onoff= DISABLE; + lex->alter_info.flags|= ALTER_KEYS_ONOFF; + } + | ENABLE_SYM KEYS + { + LEX *lex=Lex; + lex->alter_info.keys_onoff= ENABLE; + lex->alter_info.flags|= ALTER_KEYS_ONOFF; + } | ALTER opt_column field_ident SET DEFAULT signed_literal { LEX *lex=Lex; lex->alter_info.alter_list.push_back(new Alter_column($3.str,$6)); - lex->alter_info.is_simple= 0; - lex->alter_info.flags|= ALTER_CHANGE_COLUMN; + lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT; } | ALTER opt_column field_ident DROP DEFAULT { LEX *lex=Lex; lex->alter_info.alter_list.push_back(new Alter_column($3.str, (Item*) 0)); - lex->alter_info.is_simple= 0; - lex->alter_info.flags|= ALTER_CHANGE_COLUMN; + lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT; } | RENAME opt_to table_ident { @@ -2012,22 +3391,20 @@ alter_list_item: YYABORT; } LEX *lex= Lex; - lex->create_info.table_charset= + lex->create_info.table_charset= lex->create_info.default_table_charset= $5; lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET); - lex->alter_info.is_simple= 0; + lex->alter_info.flags|= ALTER_CONVERT; } - | create_table_options_space_separated + | create_table_options_space_separated { LEX *lex=Lex; - lex->alter_info.is_simple= 0; lex->alter_info.flags|= ALTER_OPTIONS; } - | order_clause + | order_clause { LEX *lex=Lex; - lex->alter_info.is_simple= 0; lex->alter_info.flags|= ALTER_ORDER; }; @@ -2040,9 +3417,10 @@ opt_ignore: | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; }; opt_restrict: - /* empty */ {} - | RESTRICT {} - | CASCADE {}; + /* empty */ { Lex->drop_mode= DROP_DEFAULT; } + | RESTRICT { Lex->drop_mode= DROP_RESTRICT; } + | CASCADE { Lex->drop_mode= DROP_CASCADE; } + ; opt_place: /* empty */ {} @@ -2060,7 +3438,7 @@ opt_to: */ slave: - START_SYM SLAVE slave_thread_opts + START_SYM SLAVE slave_thread_opts { LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_START; @@ -2542,8 +3920,12 @@ select_item: YYABORT; if ($4.str) $2->set_name($4.str,$4.length,system_charset_info); - else if (!$2->name) - $2->set_name($1,(uint) ($3 - $1), YYTHD->charset()); + else if (!$2->name) { + char *str = $1; + if (str[-1] == '`') + str--; + $2->set_name(str,(uint) ($3 - str), YYTHD->charset()); + } }; remember_name: @@ -2767,12 +4149,16 @@ simple_expr: | '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); - Lex->uncacheable(UNCACHEABLE_RAND); + LEX *lex= Lex; + lex->uncacheable(UNCACHEABLE_RAND); + lex->variables_used= 1; } | '@' ident_or_text { $$= new Item_func_get_user_var($2); - Lex->uncacheable(UNCACHEABLE_RAND); + LEX *lex= Lex; + lex->uncacheable(UNCACHEABLE_RAND); + lex->variables_used= 1; } | '@' '@' opt_var_ident_type ident_or_text opt_component { @@ -2784,6 +4170,7 @@ simple_expr: } if (!($$= get_system_var(YYTHD, (enum_var_type) $3, $4, $5))) YYABORT; + Lex->variables_used= 1; } | sum_expr | '+' expr %prec NEG { $$= $2; } @@ -2888,6 +4275,8 @@ simple_expr: { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 0);} | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new Item_date_add_interval($3, $6, $7, 0); } + | REPEAT_SYM '(' expr ',' expr ')' + { $$= new Item_func_repeat($3,$5); } | ATAN '(' expr ')' { $$= new Item_func_atan($3); } | ATAN '(' expr ',' expr ')' @@ -2904,6 +4293,8 @@ simple_expr: { $$= new Item_func_concat(* $3); } | CONCAT_WS '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_concat_ws(*$5); } + | CONTAINS_SYM '(' expr ',' expr ')' + { $$= create_func_contains($3, $5); } | CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')' { Lex->time_zone_tables_used= &fake_time_zone_tables_list; @@ -3059,6 +4450,8 @@ simple_expr: { $$= new Item_func_old_password($3); } | POSITION_SYM '(' no_in_expr IN_SYM expr ')' { $$ = new Item_func_locate($5,$3); } + | QUARTER_SYM '(' expr ')' + { $$ = new Item_func_quarter($3); } | RAND '(' expr ')' { $$= new Item_func_rand($3); Lex->uncacheable(UNCACHEABLE_RAND);} | RAND '(' ')' @@ -3070,6 +4463,11 @@ simple_expr: | ROUND '(' expr ')' { $$= new Item_func_round($3, new Item_int((char*)"0",0,1),0); } | ROUND '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,0); } + | ROW_COUNT_SYM '(' ')' + { + $$= new Item_func_row_count(); + Lex->safe_to_cache_query= 0; + } | SUBDATE_SYM '(' expr ',' expr ')' { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1);} | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' @@ -3092,6 +4490,10 @@ simple_expr: { $$= new Item_datetime_typecast($3); } | TIMESTAMP '(' expr ',' expr ')' { $$= new Item_func_add_time($3, $5, 1, 0); } + | TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')' + { $$= new Item_date_add_interval($7,$5,$3,0); } + | TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')' + { $$= new Item_func_timestamp_diff($5,$7,$3); } | TRIM '(' expr ')' { $$= new Item_func_trim($3); } | TRIM '(' LEADING expr FROM expr ')' @@ -3110,50 +4512,92 @@ simple_expr: { $$= new Item_func_trim($5,$3); } | TRUNCATE_SYM '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,1); } - | TRUE_SYM - { $$= new Item_int((char*) "TRUE",1,1); } - | UDA_CHAR_SUM '(' udf_expr_list ')' - { - if ($3 != NULL) - $$ = new Item_sum_udf_str($1, *$3); - else - $$ = new Item_sum_udf_str($1); - } - | UDA_FLOAT_SUM '(' udf_expr_list ')' - { - if ($3 != NULL) - $$ = new Item_sum_udf_float($1, *$3); - else - $$ = new Item_sum_udf_float($1); - } - | UDA_INT_SUM '(' udf_expr_list ')' - { - if ($3 != NULL) - $$ = new Item_sum_udf_int($1, *$3); - else - $$ = new Item_sum_udf_int($1); - } - | UDF_CHAR_FUNC '(' udf_expr_list ')' - { - if ($3 != NULL) - $$ = new Item_func_udf_str($1, *$3); - else - $$ = new Item_func_udf_str($1); - } - | UDF_FLOAT_FUNC '(' udf_expr_list ')' - { - if ($3 != NULL) - $$ = new Item_func_udf_float($1, *$3); - else - $$ = new Item_func_udf_float($1); - } - | UDF_INT_FUNC '(' udf_expr_list ')' + | TRUE_SYM + { $$= new Item_int((char*) "TRUE",1,1); } + | ident '.' ident '(' udf_expr_list ')' { - if ($3 != NULL) - $$ = new Item_func_udf_int($1, *$3); + LEX *lex= Lex; + sp_name *name= new sp_name($1, $3); + + name->init_qname(YYTHD); + sp_add_fun_to_lex(Lex, name); + if ($5) + $$= new Item_func_sp(name, *$5); else - $$ = new Item_func_udf_int($1); + $$= new Item_func_sp(name); } + | IDENT_sys '(' udf_expr_list ')' + { +#ifdef HAVE_DLOPEN + udf_func *udf; + + if (using_udf_functions && (udf=find_udf($1.str, $1.length))) + { + switch (udf->returns) { + case STRING_RESULT: + if (udf->type == UDFTYPE_FUNCTION) + { + if ($3 != NULL) + $$ = new Item_func_udf_str(udf, *$3); + else + $$ = new Item_func_udf_str(udf); + } + else + { + if ($3 != NULL) + $$ = new Item_sum_udf_str(udf, *$3); + else + $$ = new Item_sum_udf_str(udf); + } + break; + case REAL_RESULT: + if (udf->type == UDFTYPE_FUNCTION) + { + if ($3 != NULL) + $$ = new Item_func_udf_float(udf, *$3); + else + $$ = new Item_func_udf_float(udf); + } + else + { + if ($3 != NULL) + $$ = new Item_sum_udf_float(udf, *$3); + else + $$ = new Item_sum_udf_float(udf); + } + break; + case INT_RESULT: + if (udf->type == UDFTYPE_FUNCTION) + { + if ($3 != NULL) + $$ = new Item_func_udf_int(udf, *$3); + else + $$ = new Item_func_udf_int(udf); + } + else + { + if ($3 != NULL) + $$ = new Item_sum_udf_int(udf, *$3); + else + $$ = new Item_sum_udf_int(udf); + } + break; + default: + YYABORT; + } + } + else +#endif /* HAVE_DLOPEN */ + { + sp_name *name= sp_name_current_db_new(YYTHD, $1); + + sp_add_fun_to_lex(Lex, name); + if ($3) + $$= new Item_func_sp(name, *$3); + else + $$= new Item_func_sp(name); + } + } | UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')' { $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9); @@ -3261,8 +4705,37 @@ fulltext_options: ; udf_expr_list: - /* empty */ { $$= NULL; } - | expr_list { $$= $1;}; + /* empty */ { $$= NULL; } + | udf_expr_list2 { $$= $1;} + ; + +udf_expr_list2: + { Select->expr_list.push_front(new List); } + udf_expr_list3 + { $$= Select->expr_list.pop(); } + ; + +udf_expr_list3: + udf_expr + { + Select->expr_list.head()->push_back($1); + } + | udf_expr_list3 ',' udf_expr + { + Select->expr_list.head()->push_back($3); + } + ; + +udf_expr: + remember_name expr remember_end select_alias + { + if ($4.str) + $2->set_name($4.str,$4.length,system_charset_info); + else + $2->set_name($1,(uint) ($3 - $1), YYTHD->charset()); + $$= $2; + } + ; sum_expr: AVG_SYM '(' in_sum_expr ')' @@ -3287,14 +4760,25 @@ sum_expr: { $$= new Item_sum_unique_users($3,atoi($5.str),atoi($7.str),$9); } | MIN_SYM '(' in_sum_expr ')' { $$=new Item_sum_min($3); } +/* + According to ANSI SQL, DISTINCT is allowed and has + no sence inside MIN and MAX grouping functions; so MIN|MAX(DISTINCT ...) + is processed like an ordinary MIN | MAX() + */ + | MIN_SYM '(' DISTINCT in_sum_expr ')' + { $$=new Item_sum_min($4); } | MAX_SYM '(' in_sum_expr ')' { $$=new Item_sum_max($3); } + | MAX_SYM '(' DISTINCT in_sum_expr ')' + { $$=new Item_sum_max($4); } | STD_SYM '(' in_sum_expr ')' { $$=new Item_sum_std($3); } | VARIANCE_SYM '(' in_sum_expr ')' { $$=new Item_sum_variance($3); } | SUM_SYM '(' in_sum_expr ')' { $$=new Item_sum_sum($3); } + | SUM_SYM '(' DISTINCT in_sum_expr ')' + { $$=new Item_sum_sum_distinct($4); } | GROUP_CONCAT_SYM '(' opt_distinct { Select->in_sum_expr++; } expr_list opt_gorder_clause @@ -3408,59 +4892,80 @@ when_list2: sel->when_list.head()->push_back($5); }; +table_ref: + table_factor { $$=$1; } + | join_table { $$=$1; } + { + LEX *lex= Lex; + if (!($$= lex->current_select->nest_last_join(lex->thd))) + YYABORT; + } + ; + join_table_list: - '(' join_table_list ')' { $$=$2; } - | join_table { $$=$1; } - | join_table_list ',' join_table_list { $$=$3; } - | join_table_list normal_join join_table_list { $$=$3; } - | join_table_list STRAIGHT_JOIN join_table_list - { $$=$3 ; $1->next->straight=1; } - | join_table_list normal_join join_table_list ON expr + table_ref { $$=$1; } + | join_table_list ',' table_ref { $$=$3; } + ; + +join_table: + table_ref normal_join table_ref { $$=$3; } + | table_ref STRAIGHT_JOIN table_factor + { $3->straight=1; $$=$3 ; } + | table_ref normal_join table_ref ON expr { add_join_on($3,$5); $$=$3; } - | join_table_list normal_join join_table_list + | table_ref normal_join table_ref USING { SELECT_LEX *sel= Select; - sel->db1=$1->db; sel->table1=$1->alias; - sel->db2=$3->db; sel->table2=$3->alias; + sel->save_names_for_using_list($1, $3); } '(' using_list ')' { add_join_on($3,$7); $$=$3; } - | join_table_list LEFT opt_outer JOIN_SYM join_table_list ON expr + | table_ref LEFT opt_outer JOIN_SYM table_ref ON expr { add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } - | join_table_list LEFT opt_outer JOIN_SYM join_table_list + | table_ref LEFT opt_outer JOIN_SYM table_factor { SELECT_LEX *sel= Select; - sel->db1=$1->db; sel->table1=$1->alias; - sel->db2=$5->db; sel->table2=$5->alias; + sel->save_names_for_using_list($1, $5); } USING '(' using_list ')' { add_join_on($5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } - | join_table_list NATURAL LEFT opt_outer JOIN_SYM join_table_list + | table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor { - add_join_natural($1,$1->next); - $1->next->outer_join|=JOIN_TYPE_LEFT; + add_join_natural($1,$6); + $6->outer_join|=JOIN_TYPE_LEFT; $$=$6; } - | join_table_list RIGHT opt_outer JOIN_SYM join_table_list ON expr - { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$5; } - | join_table_list RIGHT opt_outer JOIN_SYM join_table_list + | table_ref RIGHT opt_outer JOIN_SYM table_ref ON expr + { + LEX *lex= Lex; + if (!($$= lex->current_select->convert_right_join())) + YYABORT; + add_join_on($$, $7); + } + | table_ref RIGHT opt_outer JOIN_SYM table_factor { SELECT_LEX *sel= Select; - sel->db1=$1->db; sel->table1=$1->alias; - sel->db2=$5->db; sel->table2=$5->alias; + sel->save_names_for_using_list($1, $5); } USING '(' using_list ')' - { add_join_on($1,$9); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$5; } - | join_table_list NATURAL RIGHT opt_outer JOIN_SYM join_table_list + { + LEX *lex= Lex; + if (!($$= lex->current_select->convert_right_join())) + YYABORT; + add_join_on($$, $9); + } + | table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor { - add_join_natural($1->next,$1); - $1->outer_join|=JOIN_TYPE_RIGHT; - $$=$6; + add_join_natural($6,$1); + LEX *lex= Lex; + if (!($$= lex->current_select->convert_right_join())) + YYABORT; } - | join_table_list NATURAL JOIN_SYM join_table_list - { add_join_natural($1,$1->next); $$=$4; }; + | table_ref NATURAL JOIN_SYM table_factor + { add_join_natural($1,$4); $$=$4; }; + normal_join: JOIN_SYM {} @@ -3468,7 +4973,7 @@ normal_join: | CROSS JOIN_SYM {} ; -join_table: +table_factor: { SELECT_LEX *sel= Select; sel->use_index_ptr=sel->ignore_index_ptr=0; @@ -3484,8 +4989,21 @@ join_table: sel->get_use_index(), sel->get_ignore_index()))) YYABORT; + sel->add_joined_table($$); } - | '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}' + | '(' + { + LEX *lex= Lex; + if (lex->current_select->init_nested_join(lex->thd)) + YYABORT; + } + join_table_list ')' + { + LEX *lex= Lex; + if (!($$= lex->current_select->end_nested_join(lex->thd))) + YYABORT; + } + | '{' ident table_ref LEFT OUTER JOIN_SYM table_ref ON expr '}' { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; } | '(' SELECT_SYM select_derived ')' opt_table_alias { @@ -3498,12 +5016,13 @@ join_table: (List *)0))) YYABORT; + lex->current_select->add_joined_table($$); }; select_derived: { LEX *lex= Lex; - lex->derived_tables= 1; + lex->derived_tables|= DERIVED_SUBQUERY; if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN && lex->sql_command <= (int)SQLCOM_HA_READ) || lex->sql_command == (int)SQLCOM_KILL) @@ -3594,23 +5113,29 @@ using_list: }; interval: - DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; } + interval_time_st {} + | DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; } | DAY_MICROSECOND_SYM { $$=INTERVAL_DAY_MICROSECOND; } | DAY_MINUTE_SYM { $$=INTERVAL_DAY_MINUTE; } | DAY_SECOND_SYM { $$=INTERVAL_DAY_SECOND; } - | DAY_SYM { $$=INTERVAL_DAY; } | HOUR_MICROSECOND_SYM { $$=INTERVAL_HOUR_MICROSECOND; } | HOUR_MINUTE_SYM { $$=INTERVAL_HOUR_MINUTE; } | HOUR_SECOND_SYM { $$=INTERVAL_HOUR_SECOND; } - | HOUR_SYM { $$=INTERVAL_HOUR; } | MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; } | MINUTE_MICROSECOND_SYM { $$=INTERVAL_MINUTE_MICROSECOND; } | MINUTE_SECOND_SYM { $$=INTERVAL_MINUTE_SECOND; } + | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; } + | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; }; + +interval_time_st: + DAY_SYM { $$=INTERVAL_DAY; } + | WEEK_SYM { $$=INTERVAL_WEEK; } + | HOUR_SYM { $$=INTERVAL_HOUR; } + | FRAC_SECOND_SYM { $$=INTERVAL_MICROSECOND; } | MINUTE_SYM { $$=INTERVAL_MINUTE; } | MONTH_SYM { $$=INTERVAL_MONTH; } - | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; } + | QUARTER_SYM { $$=INTERVAL_QUARTER; } | SECOND_SYM { $$=INTERVAL_SECOND; } - | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } | YEAR_SYM { $$=INTERVAL_YEAR; } ; @@ -3671,8 +5196,11 @@ having_clause: opt_escape: ESCAPE_SYM simple_expr { $$= $2; } | /* empty */ - { - $$= new Item_string("\\", 1, &my_charset_latin1); + { + + $$= ((YYTHD->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ? + new Item_string("", 0, &my_charset_latin1) : + new Item_string("\\", 1, &my_charset_latin1)); } ; @@ -3885,11 +5413,32 @@ select_var_list: | select_var_ident {} ; -select_var_ident: '@' ident_or_text +select_var_ident: + '@' ident_or_text + { + LEX *lex=Lex; + if (lex->result) + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0,(enum_field_types)0)); + else + YYABORT; + } + | ident_or_text { LEX *lex=Lex; - if (lex->result && ((select_dumpvar *)lex->result)->var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)))) + sp_pvar_t *t; + + if (!lex->spcont || !(t=lex->spcont->find_pvar(&$1))) + { + net_printf(YYTHD, ER_SP_UNDECLARED_VAR, $1.str); YYABORT; + } + if (! lex->result) + YYABORT; + else + { + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($1,1,t->offset,t->type)); + t->isset= TRUE; + } } ; @@ -3966,11 +5515,29 @@ drop: lex->drop_if_exists=$3; lex->name=$4.str; } - | DROP UDF_SYM IDENT_sys + | DROP FUNCTION_SYM if_exists sp_name { LEX *lex=Lex; + if (lex->sphead) + { + net_printf(YYTHD, ER_SP_NO_DROP_SP, "FUNCTION"); + YYABORT; + } lex->sql_command = SQLCOM_DROP_FUNCTION; - lex->udf.name = $3; + lex->drop_if_exists= $3; + lex->spname= $4; + } + | DROP PROCEDURE if_exists sp_name + { + LEX *lex=Lex; + if (lex->sphead) + { + net_printf(YYTHD, ER_SP_NO_DROP_SP, "PROCEDURE"); + YYABORT; + } + lex->sql_command = SQLCOM_DROP_PROCEDURE; + lex->drop_if_exists= $3; + lex->spname= $4; } | DROP USER { @@ -3980,8 +5547,28 @@ drop: } user_list {} - ; + | DROP VIEW_SYM if_exists table_list opt_restrict + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->sql_command= SQLCOM_DROP_VIEW; + lex->drop_if_exists= $3; + } + | DROP TRIGGER_SYM ident '.' ident + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_DROP_TRIGGER; + /* QQ: Could we loosen lock type in certain cases ? */ + if (!lex->select_lex.add_table_to_list(YYTHD, + new Table_ident($3), + (LEX_STRING*) 0, + TL_OPTION_UPDATING, + TL_WRITE)) + YYABORT; + lex->name_and_length= $5; + } + ; table_list: table_name @@ -4041,7 +5628,6 @@ replace: } insert_field_spec {} - {} ; insert_lock_option: @@ -4107,7 +5693,7 @@ ident_eq_list: ident_eq_value; ident_eq_value: - simple_ident equal expr_or_default + simple_ident_nospvar equal expr_or_default { LEX *lex=Lex; if (lex->field_list.push_back($1) || @@ -4173,7 +5759,6 @@ opt_insert_update: yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } - lex->duplicates= DUP_UPDATE; } KEY_SYM UPDATE_SYM update_list ; @@ -4211,12 +5796,12 @@ update: ; update_list: - update_list ',' simple_ident equal expr_or_default + update_list ',' simple_ident_nospvar equal expr_or_default { if (add_item_to_list(YYTHD, $3) || add_value_to_list(YYTHD, $5)) YYABORT; } - | simple_ident equal expr_or_default + | simple_ident_nospvar equal expr_or_default { if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3)) YYABORT; @@ -4321,11 +5906,11 @@ show: SHOW show_param: DATABASES wild { Lex->sql_command= SQLCOM_SHOW_DATABASES; } - | TABLES opt_db wild + | opt_full TABLES opt_db wild { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select_lex.db= $2; + lex->select_lex.db= $3; } | TABLE_SYM STATUS_SYM opt_db wild { @@ -4411,8 +5996,12 @@ show_param: { Lex->sql_command = SQLCOM_SHOW_WARNS;} | ERRORS opt_limit_clause_init { Lex->sql_command = SQLCOM_SHOW_ERRORS;} - | STATUS_SYM wild - { Lex->sql_command= SQLCOM_SHOW_STATUS; } + | opt_var_type STATUS_SYM wild + { + THD *thd= YYTHD; + thd->lex->sql_command= SQLCOM_SHOW_STATUS; + thd->lex->option_type= (enum_var_type) $1; + } | INNOBASE_SYM STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_INNODB_STATUS; WARN_DEPRECATED("SHOW INNODB STATUS", "SHOW ENGINE INNODB STATUS"); } | opt_full PROCESSLIST_SYM @@ -4469,9 +6058,19 @@ show_param: } | CREATE TABLE_SYM table_ident { - Lex->sql_command = SQLCOM_SHOW_CREATE; - if (!Select->add_table_to_list(YYTHD, $3, NULL,0)) + LEX *lex= Lex; + lex->sql_command = SQLCOM_SHOW_CREATE; + if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL,0)) + YYABORT; + lex->only_view= 0; + } + | CREATE VIEW_SYM table_ident + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_SHOW_CREATE; + if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0)) YYABORT; + lex->only_view= 1; } | MASTER_SYM STATUS_SYM { @@ -4480,7 +6079,29 @@ show_param: | SLAVE STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - }; + } + | CREATE PROCEDURE sp_name + { + LEX *lex= Lex; + + lex->sql_command = SQLCOM_SHOW_CREATE_PROC; + lex->spname= $3; + } + | CREATE FUNCTION_SYM sp_name + { + LEX *lex= Lex; + + lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; + lex->spname= $3; + } + | PROCEDURE STATUS_SYM wild + { + Lex->sql_command = SQLCOM_SHOW_STATUS_PROC; + } + | FUNCTION_SYM STATUS_SYM wild + { + Lex->sql_command = SQLCOM_SHOW_STATUS_FUNC; + }; show_engine_param: STATUS_SYM @@ -4670,18 +6291,23 @@ purge_option: /* kill threads */ kill: - KILL_SYM expr + KILL_SYM kill_option expr { LEX *lex=Lex; - if ($2->fix_fields(lex->thd, 0, &$2) || $2->check_cols(1)) + if ($3->fix_fields(lex->thd, 0, &$3) || $3->check_cols(1)) { send_error(lex->thd, ER_SET_CONSTANTS_ONLY); YYABORT; } lex->sql_command=SQLCOM_KILL; - lex->thread_id= (ulong) $2->val_int(); + lex->thread_id= (ulong) $3->val_int(); }; +kill_option: + /* empty */ { Lex->type= 0; } + | CONNECTION_SYM { Lex->type= 0; } + | QUERY_SYM { Lex->type= ONLY_KILL_QUERY; }; + /* change database */ use: USE_SYM ident @@ -4892,8 +6518,24 @@ NUM_literal: NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } | LONG_NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } | ULONGLONG_NUM { $$ = new Item_uint($1.str, $1.length); } - | REAL_NUM { $$ = new Item_real($1.str, $1.length); } - | FLOAT_NUM { $$ = new Item_float($1.str, $1.length); } + | REAL_NUM + { + $$= new Item_real($1.str, $1.length); + if (YYTHD->net.report_error) + { + send_error(YYTHD, 0, NullS); + YYABORT; + } + } + | FLOAT_NUM + { + $$ = new Item_float($1.str, $1.length); + if (YYTHD->net.report_error) + { + send_error(YYTHD, 0, NullS); + YYABORT; + } + } ; /********************************************************************** @@ -4901,7 +6543,7 @@ NUM_literal: **********************************************************************/ insert_ident: - simple_ident { $$=$1; } + simple_ident_nospvar { $$=$1; } | table_wild { $$=$1; }; table_wild: @@ -4923,30 +6565,110 @@ order_ident: expr { $$=$1; }; simple_ident: + ident + { + sp_pvar_t *spv; + LEX *lex = Lex; + sp_pcontext *spc = lex->spcont; + + if (spc && (spv = spc->find_pvar(&$1))) + { /* We're compiling a stored procedure and found a variable */ + $$ = (Item*) new Item_splocal($1, spv->offset); + lex->variables_used= 1; + lex->safe_to_cache_query=0; + } + else + { + SELECT_LEX *sel=Select; + $$= (sel->parsing_place != IN_HAVING || + sel->get_in_sum_expr() > 0) ? + (Item*) new Item_field(NullS,NullS,$1.str) : + (Item*) new Item_ref(NullS,NullS,$1.str); + } + } + | simple_ident_q { $$= $1; } + ; + +simple_ident_nospvar: ident { SELECT_LEX *sel=Select; $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,NullS,$1.str) : - (Item*) new Item_ref(NullS, NullS, $1.str); + (Item*) new Item_ref(NullS,NullS,$1.str); } - | ident '.' ident + | simple_ident_q { $$= $1; } + ; + +simple_ident_q: + ident '.' ident { THD *thd= YYTHD; LEX *lex= thd->lex; - SELECT_LEX *sel= lex->current_select; - if (sel->no_table_names_allowed) - { - my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, - ER(ER_TABLENAME_NOT_ALLOWED_HERE), - MYF(0), $1.str, thd->where); - } - $$= (sel->parsing_place != IN_HAVING || - sel->get_in_sum_expr() > 0) ? - (Item*) new Item_field(NullS,$1.str,$3.str) : - (Item*) new Item_ref(NullS, $1.str, $3.str); - } + + /* + FIXME This will work ok in simple_ident_nospvar case because + we can't meet simple_ident_nospvar in trigger now. But it + should be changed in future. + */ + if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER && + (!my_strcasecmp(system_charset_info, $1.str, "NEW") || + !my_strcasecmp(system_charset_info, $1.str, "OLD"))) + { + bool new_row= ($1.str[0]=='N' || $1.str[0]=='n'); + + if (lex->trg_chistics.event == TRG_EVENT_INSERT && + !new_row) + { + net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "OLD", + "on INSERT"); + YYABORT; + } + + if (lex->trg_chistics.event == TRG_EVENT_DELETE && + new_row) + { + net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "NEW", + "on DELETE"); + YYABORT; + } + + Item_trigger_field *trg_fld= + new Item_trigger_field(new_row ? Item_trigger_field::NEW_ROW : + Item_trigger_field::OLD_ROW, + $3.str); + + if (lex->trg_table && + trg_fld->setup_field(thd, lex->trg_table, + lex->trg_chistics.event)) + { + /* + FIXME. Far from perfect solution. See comment for + "SET NEW.field_name:=..." for more info. + */ + net_printf(YYTHD, ER_BAD_FIELD_ERROR, $3.str, + new_row ? "NEW": "OLD"); + YYABORT; + } + + $$= (Item *)trg_fld; + } + else + { + SELECT_LEX *sel= lex->current_select; + if (sel->no_table_names_allowed) + { + my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, + ER(ER_TABLENAME_NOT_ALLOWED_HERE), + MYF(0), $1.str, thd->where); + } + $$= (sel->parsing_place != IN_HAVING || + sel->get_in_sum_expr() > 0) ? + (Item*) new Item_field(NullS,$1.str,$3.str) : + (Item*) new Item_ref(NullS,$1.str,$3.str); + } + } | '.' ident '.' ident { THD *thd= YYTHD; @@ -5109,6 +6831,7 @@ keyword: | AFTER_SYM {} | AGAINST {} | AGGREGATE_SYM {} + | ALGORITHM_SYM {} | ANY_SYM {} | ASCII_SYM {} | AUTO_INC {} @@ -5124,6 +6847,7 @@ keyword: | BYTE_SYM {} | BTREE_SYM {} | CACHE_SYM {} + | CASCADED {} | CHANGED {} | CHARSET {} | CHECKSUM_SYM {} @@ -5137,12 +6861,14 @@ keyword: | COMPRESSED_SYM {} | CONCURRENT {} | CONSISTENT_SYM {} + | CONTAINS_SYM {} | CUBE_SYM {} | DATA_SYM {} | DATETIME {} | DATE_SYM {} | DAY_SYM {} | DEALLOCATE_SYM {} + | DEFINER_SYM {} | DELAY_KEY_WRITE_SYM {} | DES_KEY_FILE {} | DIRECTORY_SYM {} @@ -5162,6 +6888,7 @@ keyword: | EXPANSION_SYM {} | EXTENDED_SYM {} | FAST_SYM {} + | FOUND_SYM {} | DISABLE_SYM {} | ENABLE_SYM {} | FULL {} @@ -5169,6 +6896,7 @@ keyword: | FIRST_SYM {} | FIXED_SYM {} | FLUSH_SYM {} + | FRAC_SECOND_SYM {} | GEOMETRY_SYM {} | GEOMETRYCOLLECTION {} | GET_FORMAT {} @@ -5180,6 +6908,7 @@ keyword: | HOSTS_SYM {} | HOUR_SYM {} | IDENTIFIED_SYM {} + | INVOKER_SYM {} | IMPORT {} | INDEXES {} | ISOLATION {} @@ -5187,6 +6916,8 @@ keyword: | INNOBASE_SYM {} | INSERT_METHOD {} | RELAY_THREAD {} + | LABEL_SYM {} + | LANGUAGE_SYM {} | LAST_SYM {} | LEAVES {} | LEVEL_SYM {} @@ -5214,6 +6945,7 @@ keyword: | MAX_QUERIES_PER_HOUR {} | MAX_UPDATES_PER_HOUR {} | MEDIUM_SYM {} + | MERGE_SYM {} | MICROSECOND_SYM {} | MINUTE_SYM {} | MIN_ROWS {} @@ -5223,6 +6955,7 @@ keyword: | MULTILINESTRING {} | MULTIPOINT {} | MULTIPOLYGON {} + | NAME_SYM {} | NAMES_SYM {} | NATIONAL_SYM {} | NCHAR_SYM {} @@ -5245,6 +6978,7 @@ keyword: | PREV_SYM {} | PROCESS {} | PROCESSLIST_SYM {} + | QUARTER_SYM {} | QUERY_SYM {} | QUICK {} | RAID_0_SYM {} @@ -5261,6 +6995,7 @@ keyword: | RESET_SYM {} | RESOURCES {} | RESTORE_SYM {} + | RETURNS_SYM {} | ROLLBACK_SYM {} | ROLLUP_SYM {} | ROWS_SYM {} @@ -5269,6 +7004,7 @@ keyword: | RTREE_SYM {} | SAVEPOINT_SYM {} | SECOND_SYM {} + | SECURITY_SYM {} | SERIAL_SYM {} | SERIALIZABLE_SYM {} | SESSION_SYM {} @@ -5293,23 +7029,29 @@ keyword: | SUPER_SYM {} | TABLESPACE {} | TEMPORARY {} + | TEMPTABLE_SYM {} | TEXT_SYM {} | TRANSACTION_SYM {} | TRUNCATE_SYM {} | TIMESTAMP {} + | TIMESTAMP_ADD {} + | TIMESTAMP_DIFF {} | TIME_SYM {} | TYPE_SYM {} | TYPES_SYM {} | UDF_RETURNS_SYM {} - | UDF_SYM {} + | FUNCTION_SYM {} | UNCOMMITTED_SYM {} + | UNDEFINED_SYM {} | UNICODE_SYM {} | UNTIL_SYM {} | USER {} | USE_FRM {} | VARIABLES {} + | VIEW_SYM {} | VALUE_SYM {} | WARNINGS {} + | WEEK_SYM {} | WORK_SYM {} | X509_SYM {} | YEAR_SYM {} @@ -5361,15 +7103,107 @@ opt_var_ident_type: ; option_value: - '@' ident_or_text equal expr - { - Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); - } + '@' ident_or_text equal expr + { + LEX *lex= Lex; + + if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) + { + /* + We have to use special instruction in functions and triggers + because sp_instr_stmt will close all tables and thus ruin + execution of statement invoking function or trigger. + + We also do not want to allow expression with subselects in + this case. + */ + if (lex->query_tables) + { + send_error(YYTHD, ER_SP_SUBSELECT_NYI); + YYABORT; + } + sp_instr_set_user_var *i= + new sp_instr_set_user_var(lex->sphead->instructions(), + lex->spcont, $2, $4); + lex->sphead->add_instr(i); + } + else + lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); + + } | internal_variable_name equal set_expr_or_default { LEX *lex=Lex; - lex->var_list.push_back(new set_var(lex->option_type, $1.var, - &$1.base_name, $3)); + + if ($1.var == &trg_new_row_fake_var) + { + /* We are in trigger and assigning value to field of new row */ + Item *it; + sp_instr_set_trigger_field *i; + if (lex->query_tables) + { + send_error(YYTHD, ER_SP_SUBSELECT_NYI); + YYABORT; + } + if ($3) + it= $3; + else + { + /* QQ: Shouldn't this be field's default value ? */ + it= new Item_null(); + } + i= new sp_instr_set_trigger_field(lex->sphead->instructions(), + lex->spcont, $1.base_name, it); + if (lex->trg_table && i->setup_field(YYTHD, lex->trg_table, + lex->trg_chistics.event)) + { + /* + FIXME. Now we are catching this kind of errors only + during opening tables. But this doesn't save us from most + common user error - misspelling field name, because we + will bark too late in this case... Moreover it is easy to + make table unusable with such kind of error... + + So in future we either have to parse trigger definition + second time during create trigger or gather all trigger + fields in one list and perform setup_field() for them as + separate stage. + + Error message also should be improved. + */ + net_printf(YYTHD, ER_BAD_FIELD_ERROR, $1.base_name, "NEW"); + YYABORT; + } + lex->sphead->add_instr(i); + } + else if ($1.var) + { /* System variable */ + lex->var_list.push_back(new set_var(lex->option_type, $1.var, + &$1.base_name, $3)); + } + else + { + /* An SP local variable */ + sp_pcontext *ctx= lex->spcont; + sp_pvar_t *spv; + sp_instr_set *i; + Item *it; + + spv= ctx->find_pvar(&$1.base_name); + + if ($3) + it= $3; + else if (spv->dflt) + it= spv->dflt; + else + it= new Item_null(); + i= new sp_instr_set(lex->sphead->instructions(), ctx, + spv->offset, it, spv->type); + i->tables= lex->query_tables; + lex->query_tables= 0; + lex->sphead->add_instr(i); + spv->isset= TRUE; + } } | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default { @@ -5427,33 +7261,76 @@ option_value: internal_variable_name: ident { - sys_var *tmp=find_sys_var($1.str, $1.length); - if (!tmp) - YYABORT; - $$.var= tmp; - $$.base_name.str=0; - $$.base_name.length=0; - /* - If this is time_zone variable we should open time zone - describing tables - */ - if (tmp == &sys_time_zone) - Lex->time_zone_tables_used= &fake_time_zone_tables_list; + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + sp_pvar_t *spv; + + /* We have to lookup here since local vars can shadow sysvars */ + if (!spc || !(spv = spc->find_pvar(&$1))) + { + /* Not an SP local variable */ + sys_var *tmp=find_sys_var($1.str, $1.length); + if (!tmp) + YYABORT; + $$.var= tmp; + $$.base_name.str=0; + $$.base_name.length=0; + /* + If this is time_zone variable we should open time zone + describing tables + */ + if (tmp == &sys_time_zone) + Lex->time_zone_tables_used= &fake_time_zone_tables_list; + } + else + { + /* An SP local variable */ + $$.var= NULL; + $$.base_name= $1; + } } | ident '.' ident { + LEX *lex= Lex; if (check_reserved_words(&$1)) { yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } - sys_var *tmp=find_sys_var($3.str, $3.length); - if (!tmp) - YYABORT; - if (!tmp->is_struct()) - net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); - $$.var= tmp; - $$.base_name= $1; + if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER && + (!my_strcasecmp(system_charset_info, $1.str, "NEW") || + !my_strcasecmp(system_charset_info, $1.str, "OLD"))) + { + if ($1.str[0]=='O' || $1.str[0]=='o') + { + net_printf(YYTHD, ER_TRG_CANT_CHANGE_ROW, "OLD", ""); + YYABORT; + } + if (lex->trg_chistics.event == TRG_EVENT_DELETE) + { + net_printf(YYTHD, ER_TRG_NO_SUCH_ROW_IN_TRG, "NEW", + "on DELETE"); + YYABORT; + } + if (lex->trg_chistics.action_time == TRG_ACTION_AFTER) + { + net_printf(YYTHD, ER_TRG_CANT_CHANGE_ROW, "NEW", "after "); + YYABORT; + } + /* This special combination will denote field of NEW row */ + $$.var= &trg_new_row_fake_var; + $$.base_name= $3; + } + else + { + sys_var *tmp=find_sys_var($3.str, $3.length); + if (!tmp) + YYABORT; + if (!tmp->is_struct()) + net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); + $$.var= tmp; + $$.base_name= $1; + } } | DEFAULT '.' ident { @@ -5687,8 +7564,10 @@ grant_privilege: | SUPER_SYM { Lex->grant |= SUPER_ACL;} | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;} | LOCK_SYM TABLES { Lex->grant |= LOCK_TABLES_ACL; } - | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL;} - | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL;} + | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL; } + | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL; } + | CREATE VIEW_SYM { Lex->grant |= CREATE_VIEW_ACL; } + | SHOW VIEW_SYM { Lex->grant |= SHOW_VIEW_ACL; } ; @@ -6077,3 +7956,47 @@ subselect_end: lex->current_select = lex->current_select->return_after_parsing(); }; +opt_view_list: + /* empty */ {} + | '(' view_list ')' + ; + +view_list: + ident + { + Lex->view_list.push_back((LEX_STRING*) + sql_memdup(&$1, sizeof(LEX_STRING))); + } + | view_list ',' ident + { + Lex->view_list.push_back((LEX_STRING*) + sql_memdup(&$3, sizeof(LEX_STRING))); + } + ; + +or_replace: + /* empty */ { Lex->create_view_mode= VIEW_CREATE_NEW; } + | OR_SYM REPLACE { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; } + ; + +algorithm: + /* empty */ + { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; } + | ALGORITHM_SYM EQ UNDEFINED_SYM + { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; } + | ALGORITHM_SYM EQ MERGE_SYM + { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; } + | ALGORITHM_SYM EQ TEMPTABLE_SYM + { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; } + ; +check_option: + /* empty */ + { Lex->create_view_check= VIEW_CHECK_NONE; } + | WITH CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_CASCADED; } + | WITH CASCADED CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_CASCADED; } + | WITH LOCAL_SYM CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_LOCAL; } + ; + -- cgit v1.2.1 From c3531618f1727e3d785c9ba38a99ff39c5b7ed2d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 11:37:59 +0100 Subject: Build fixes to make it compile. sql/handler.cc: Build fixes. sql/log_event.cc: Build fixes. --- sql/handler.cc | 2 +- sql/log_event.cc | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index b2acb262763..b61d28e035a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -656,7 +656,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) } thd->variables.tx_isolation=thd->session_tx_isolation; if (operation_done) - statistic_increment(ha_rollback_count,&LOCK_status); + statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status); thd->proc_info= save_proc_info; } #endif /* USING_TRANSACTIONS */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 7fba19cb000..e8dc6a8827b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1362,7 +1362,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) Thank you. */ thd->catalog= (char*) catalog; - thd->db= (char*) rewrite_db(db); // thd->db_length is set later if needed + thd->db_length= db_len; + thd->db= (char*) rewrite_db(db, &thd->db_length); thd->variables.auto_increment_increment= auto_increment_increment; thd->variables.auto_increment_offset= auto_increment_offset; -- cgit v1.2.1 From eed282d6dd82450b39c4d06b27d1c4dd416d7369 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 12:28:34 +0100 Subject: Various build fixes. sql/mysql_priv.h: Fix build problems (causing link errors with the Sun compiler). sql/net_serv.cc: Corrected macro definition. sql/sql_base.cc: Fixed build problems (for broken HP compiler). sql/sql_show.cc: 64-bit build fix. --- sql/mysql_priv.h | 4 ++-- sql/net_serv.cc | 2 +- sql/sql_base.cc | 3 ++- sql/sql_show.cc | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 20ede9a623e..7d1ffe97e08 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -566,8 +566,8 @@ int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, int mysql_union(THD *thd, LEX *lex, select_result *result, SELECT_LEX_UNIT *unit); int mysql_handle_derived(LEX *lex, int (*processor)(THD *thd, - st_lex *lex, - st_table_list *table)); + LEX *lex, + TABLE_LIST *table)); int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *t); int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t); Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, diff --git a/sql/net_serv.cc b/sql/net_serv.cc index bcb1f8634c0..02fc1691b8b 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -96,7 +96,7 @@ extern void query_cache_insert(NET *net, const char *packet, ulong length); #define update_statistics(A) A #else #define update_statistics(A) -#define thd_increment_bytes_sent() +#define thd_increment_bytes_sent(N) #endif #define TEST_BLOCKING 8 diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b518af80a43..eeb34f6b600 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3056,6 +3056,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) SELECT_LEX *select_lex= thd->lex->current_select; Item_arena *arena= thd->current_arena, backup; bool save_wrapper= thd->lex->current_select->no_wrap_view_item; + TABLE_LIST *table= NULL; // For HP compilers DBUG_ENTER("setup_conds"); if (select_lex->conds_processed_with_permanent_arena || @@ -3075,7 +3076,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) } /* Check if we are using outer joins */ - for (TABLE_LIST *table= tables; table; table= table->next_local) + for (table= tables; table; table= table->next_local) { TABLE_LIST *embedded; TABLE_LIST *embedding= table; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 557ec1bd5d2..7043379bf8f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1965,7 +1965,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, switch (show_type) { case SHOW_LONG_STATUS: case SHOW_LONG_CONST_STATUS: - value= ((char *) status_var + (uint) value); + value= ((char *) status_var + (ulong) value); /* fall through */ case SHOW_LONG: case SHOW_LONG_CONST: -- cgit v1.2.1 From 9e921615a1c3147961dc4a8314ebb0e455ea105b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 14:34:00 +0200 Subject: post-review fixes mysql-test/r/rpl_rotate_logs.result: removed host dependence in error messages mysql-test/t/rpl_rotate_logs.test: removed host dependence in error messages mysys/my_error.c: comment about using my_error family functions sql/filesort.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/ha_innodb.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/handler.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/item.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/item_cmpfunc.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/item_func.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/item_strfunc.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/item_subselect.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/item_sum.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/lock.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/log.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/mysql_priv.h: error check moved to fill_record sql/mysqld.cc: fixed error messages sql/parse_file.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/protocol.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/protocol_cursor.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/repl_failsafe.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/set_var.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/slave.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sp.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sp_head.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sp_rcontext.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_acl.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_analyse.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_base.cc: changing my_error on my_message and my_printf_error where if they are prefered error check moved to fill_record sql/sql_class.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_class.h: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_db.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_delete.cc: changing my_error on my_message and my_printf_error where if they are prefered error check moved to fill_record sql/sql_handler.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_help.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_insert.cc: changing my_error on my_message and my_printf_error where if they are prefered error check moved to fill_record sql/sql_lex.cc: layout fixed sql/sql_load.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_map.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_parse.cc: error check moved to fill_record changing my_error on my_message and my_printf_error where if they are prefered sql/sql_prepare.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_rename.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_repl.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_select.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_show.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_table.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_trigger.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_udf.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_union.cc: error check moved to fill_record sql/sql_update.cc: error check moved to fill_record sql/sql_view.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/sql_yacc.yy: changing my_error on my_message and my_printf_error where if they are prefered sql/table.cc: changing my_error on my_message and my_printf_error where if they are prefered sql/unireg.cc: changing my_error on my_message and my_printf_error where if they are prefered --- sql/filesort.cc | 3 +- sql/ha_innodb.cc | 6 +- sql/handler.cc | 23 ++-- sql/item.cc | 34 +++--- sql/item_cmpfunc.cc | 9 +- sql/item_func.cc | 29 ++--- sql/item_strfunc.cc | 17 +-- sql/item_subselect.cc | 3 +- sql/item_sum.cc | 9 +- sql/lock.cc | 6 +- sql/log.cc | 5 +- sql/mysql_priv.h | 10 +- sql/mysqld.cc | 3 +- sql/parse_file.cc | 39 ++++--- sql/protocol.cc | 3 +- sql/protocol_cursor.cc | 3 +- sql/repl_failsafe.cc | 28 +++-- sql/set_var.cc | 69 +++++++----- sql/slave.cc | 14 +-- sql/sp.cc | 3 +- sql/sp_head.cc | 7 +- sql/sp_rcontext.cc | 15 +-- sql/sql_acl.cc | 81 ++++++++------ sql/sql_analyse.cc | 15 ++- sql/sql_base.cc | 79 +++++++++++--- sql/sql_class.cc | 17 +-- sql/sql_class.h | 4 +- sql/sql_db.cc | 32 +++--- sql/sql_delete.cc | 26 +++-- sql/sql_handler.cc | 4 +- sql/sql_help.cc | 2 +- sql/sql_insert.cc | 38 +++---- sql/sql_lex.cc | 2 +- sql/sql_load.cc | 9 +- sql/sql_map.cc | 8 +- sql/sql_parse.cc | 283 ++++++++++++++++++++++++++++++------------------- sql/sql_prepare.cc | 2 +- sql/sql_rename.cc | 9 +- sql/sql_repl.cc | 29 ++--- sql/sql_select.cc | 18 ++-- sql/sql_show.cc | 13 +-- sql/sql_table.cc | 135 ++++++++++++++--------- sql/sql_trigger.cc | 14 +-- sql/sql_udf.cc | 23 ++-- sql/sql_union.cc | 2 +- sql/sql_update.cc | 54 ++++------ sql/sql_view.cc | 36 ++++--- sql/sql_yacc.yy | 217 +++++++++++++++++++++++-------------- sql/table.cc | 22 ++-- sql/unireg.cc | 4 +- 50 files changed, 924 insertions(+), 592 deletions(-) (limited to 'sql') diff --git a/sql/filesort.cc b/sql/filesort.cc index ef8148616e5..09d51e31291 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -278,7 +278,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, } } if (error) - my_error(ER_FILSORT_ABORT,MYF(ME_ERROR+ME_WAITTANG)); + my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT), + MYF(ME_ERROR+ME_WAITTANG)); else statistic_add(thd->status_var.filesort_rows, (ulong) records, &LOCK_status); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 547acb63766..c93edef0795 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -462,8 +462,10 @@ innobase_mysql_tmpfile(void) if (fd2 < 0) { DBUG_PRINT("error",("Got error %d on dup",fd2)); my_errno=errno; - my_error(EE_OUT_OF_FILERESOURCES, - MYF(ME_BELL+ME_WAITTANG), filename, my_errno); + my_printf_error(EE_OUT_OF_FILERESOURCES, + ER(EE_OUT_OF_FILERESOURCES), + MYF(ME_BELL+ME_WAITTANG), + filename, my_errno); } my_close(fd, MYF(MY_WME)); } diff --git a/sql/handler.cc b/sql/handler.cc index 5185e7f8921..62b6b591b3d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -515,7 +515,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if ((error=ndbcluster_commit(thd,trans->ndb_tid))) { if (error == -1) - my_error(ER_ERROR_DURING_COMMIT, MYF(0)); + my_message_(ER_ERROR_DURING_COMMIT, ER(ER_ERROR_DURING_COMMIT), + MYF(0)); error=1; } if (trans == &thd->transaction.all) @@ -584,7 +585,8 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) if ((error=ndbcluster_rollback(thd, trans->ndb_tid))) { if (error == -1) - my_error(ER_ERROR_DURING_ROLLBACK, MYF(0)); + my_message(ER_ERROR_DURING_ROLLBACK, ER(ER_ERROR_DURING_ROLLBACK), + MYF(0)); error=1; } trans->ndb_tid = 0; @@ -1183,7 +1185,8 @@ void handler::print_error(int error, myf errflag) str.length(max_length-4); str.append("..."); } - my_error(ER_DUP_ENTRY,MYF(0),str.c_ptr(),key_nr+1); + my_printf_error(ER_DUP_ENTRY, ER(ER_DUP_ENTRY), MYF(0), + str.c_ptr(), key_nr+1); DBUG_VOID_RETURN; } textno=ER_DUP_KEY; @@ -1205,7 +1208,7 @@ void handler::print_error(int error, myf errflag) textno=ER_CRASHED_ON_REPAIR; break; case HA_ERR_OUT_OF_MEM: - my_error(ER_OUT_OF_RESOURCES,errflag); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), errflag); DBUG_VOID_RETURN; case HA_ERR_WRONG_COMMAND: textno=ER_ILLEGAL_HA; @@ -1251,9 +1254,13 @@ void handler::print_error(int error, myf errflag) { const char* engine= table_type(); if (temporary) - my_error(ER_GET_TEMPORARY_ERRMSG,MYF(0),error,str.ptr(),engine); + my_printf_error(ER_GET_TEMPORARY_ERRMSG, + ER(ER_GET_TEMPORARY_ERRMSG), MYF(0), + error, str.ptr(), engine); else - my_error(ER_GET_ERRMSG,MYF(0),error,str.ptr(),engine); + my_printf_error(ER_GET_ERRMSG, + ER(ER_GET_ERRMSG), MYF(0), + error, str.ptr(), engine); } else my_error(ER_GET_ERRNO,errflag,error); @@ -1381,7 +1388,9 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, error=table.file->create(name,&table,create_info); VOID(closefrm(&table)); if (error) - my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error); + my_printf_error(ER_CANT_CREATE_TABLE, ER(ER_CANT_CREATE_TABLE), + MYF(ME_BELL+ME_WAITTANG), + name,error); DBUG_RETURN(error != 0); } diff --git a/sql/item.cc b/sql/item.cc index 7279c18099b..ff6b74144a8 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1512,8 +1512,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { if (!(*refer)->fixed) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); + my_printf_error(ER_ILLEGAL_REFERENCE, ER(ER_ILLEGAL_REFERENCE), + MYF(0), name, "forward reference in item list"); return TRUE; } @@ -2418,8 +2418,9 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { if (!(*ref)->fixed) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); + my_printf_error(ER_ILLEGAL_REFERENCE, + ER(ER_ILLEGAL_REFERENCE), MYF(0), + name, "forward reference in item list"); return TRUE; } mark_as_dependent(thd, last, thd->lex->current_select, @@ -2433,8 +2434,9 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) { if (!(*ref)->fixed) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - "forward reference in item list"); + my_printf_error(ER_ILLEGAL_REFERENCE, + ER(ER_ILLEGAL_REFERENCE), MYF(0), + name, "forward reference in item list"); return TRUE; } ref= thd->lex->current_select->ref_pointer_array + counter; @@ -2454,10 +2456,11 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) thd->lex->current_select->having_fix_field))) || !(*ref)->fixed) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), name, - ((*ref)->with_sum_func? - "reference on group function": - "forward reference in item list")); + my_printf_error(ER_ILLEGAL_REFERENCE, ER(ER_ILLEGAL_REFERENCE), MYF(0), + name, + ((*ref)->with_sum_func? + "reference on group function": + "forward reference in item list")); return TRUE; } max_length= (*ref)->max_length; @@ -3115,11 +3118,12 @@ bool Item_type_holder::join_types(THD *thd, Item *item) *old_derivation= collation.derivation_name(); if (item_type == STRING_RESULT && collation.aggregate(item->collation)) { - my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), - old_cs, old_derivation, - item->collation.collation->name, - item->collation.derivation_name(), - "UNION"); + my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, + ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), + old_cs, old_derivation, + item->collation.collation->name, + item->collation.derivation_name(), + "UNION"); return 1; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f680ab1f20f..59d21cdfc59 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -53,10 +53,11 @@ static void agg_cmp_type(Item_result *type, Item **items, uint nitems) static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); + my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, + ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); } diff --git a/sql/item_func.cc b/sql/item_func.cc index b09824fb184..f9cf7341405 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -45,10 +45,11 @@ bool check_reserved_words(LEX_STRING *name) static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); + my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, + ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + fname); } static void my_coll_agg_error(DTCollation &c1, @@ -56,11 +57,12 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c3, const char *fname) { - my_error(ER_CANT_AGGREGATE_3COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - c3.collation->name,c3.derivation_name(), - fname); + my_printf_error(ER_CANT_AGGREGATE_3COLLATIONS, + ER(ER_CANT_AGGREGATE_3COLLATIONS), MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + c3.collation->name, c3.derivation_name(), + fname); } @@ -74,7 +76,8 @@ static void my_coll_agg_error(Item** args, uint count, const char *fname) args[2]->collation, fname); else - my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname); + my_printf_error(ER_CANT_AGGREGATE_NCOLLATIONS, + ER(ER_CANT_AGGREGATE_NCOLLATIONS), MYF(0),fname); } @@ -3112,7 +3115,8 @@ err: key=NO_SUCH_KEY; return 0; } - my_error(ER_FT_MATCHING_KEY_NOT_FOUND,MYF(0)); + my_message(ER_FT_MATCHING_KEY_NOT_FOUND, + ER(ER_FT_MATCHING_KEY_NOT_FOUND), MYF(0)); return 1; } @@ -3241,7 +3245,8 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, { if (!var->is_struct()) { - my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str); + my_printf_error(ER_VARIABLE_IS_NOT_STRUCT, ER(ER_VARIABLE_IS_NOT_STRUCT), + MYF(0), base_name->str); return 0; } } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b3665edad39..6e9467a7a71 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -42,10 +42,11 @@ String my_empty_string("",default_charset_info); static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); + my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, + ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + fname); } uint nr_of_decimals(const char *str) @@ -2243,7 +2244,8 @@ void Item_func_set_collation::fix_length_and_dec() { if (!(set_collation= get_charset_by_name(colname,MYF(0)))) { - my_error(ER_UNKNOWN_COLLATION, MYF(0), colname); + my_printf_error(ER_UNKNOWN_COLLATION, ER(ER_UNKNOWN_COLLATION), MYF(0), + colname); return; } } @@ -2251,8 +2253,9 @@ void Item_func_set_collation::fix_length_and_dec() if (!set_collation || !my_charset_same(args[0]->collation.collation,set_collation)) { - my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), - colname,args[0]->collation.collation->csname); + my_printf_error(ER_COLLATION_CHARSET_MISMATCH, + ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), + colname, args[0]->collation.collation->csname); return; } collation.set(set_collation, DERIVATION_EXPLICIT); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8fe6e5c81dd..d2d9aa8c8b6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -167,7 +167,8 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) // We can't substitute aggregate functions like "SELECT (max(i))" if (substype() == SINGLEROW_SUBS && (*ref)->with_sum_func) { - my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0)); + my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE), + MYF(0)); return TRUE; } return ret; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b355cc15806..8ec2e8fa9d9 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -220,7 +220,8 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!thd->allow_sum_func) { - my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); + my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE), + MYF(0)); return TRUE; } thd->allow_sum_func=0; // No included group funcs @@ -255,7 +256,8 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item *item= args[0]; if (!thd->allow_sum_func) { - my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); + my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE), + MYF(0)); return TRUE; } thd->allow_sum_func=0; // No included group funcs @@ -2065,7 +2067,8 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (!thd->allow_sum_func) { - my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); + my_message(ER_INVALID_GROUP_FUNC_USE, ER(ER_INVALID_GROUP_FUNC_USE), + MYF(0)); return TRUE; } diff --git a/sql/lock.cc b/sql/lock.cc index debfb900c23..e11c48a7a7e 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -430,7 +430,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_error(ER_OPEN_AS_READONLY,MYF(0),table->table_name); + my_printf_error(ER_OPEN_AS_READONLY, ER(ER_OPEN_AS_READONLY), MYF(0), + table->table_name); my_free((gptr) sql_lock,MYF(0)); return 0; } @@ -794,7 +795,8 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, { if (thd->global_read_lock) // This thread had the read locks { - my_error(ER_CANT_UPDATE_WITH_READLOCK,MYF(0)); + my_message(ER_CANT_UPDATE_WITH_READLOCK, + ER(ER_CANT_UPDATE_WITH_READLOCK), MYF(0)); (void) pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(1); } diff --git a/sql/log.cc b/sql/log.cc index ab080366f95..429ef8bd339 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1515,9 +1515,10 @@ err: if (error) { if (my_errno == EFBIG) - my_error(ER_TRANS_CACHE_FULL, MYF(0)); + my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(0)); else - my_error(ER_ERROR_ON_WRITE, MYF(0), name, errno); + my_printf_error(ER_ERROR_ON_WRITE, ER(ER_ERROR_ON_WRITE), MYF(0), + name, errno); write_error=1; } if (file == &log_file) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a8ca32f3d7e..aa6ce7ba888 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -608,8 +608,8 @@ bool mysql_rename_table(enum db_type base, bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List &keys); bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info); -int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, - Item **conds, uint order_num, ORDER *order); +bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, + Item **conds, uint order_num, ORDER *order); bool mysql_update(THD *thd,TABLE_LIST *tables,List &fields, List &values,COND *conds, uint order_num, ORDER *order, ha_rows limit, @@ -813,8 +813,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table, bool return_if_owned_by_thd=0); bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables); void copy_field_from_tmp_record(Field *field,int offset); -int fill_record(List &fields,List &values, bool ignore_errors); -int fill_record(Field **field,List &values, bool ignore_errors); +bool fill_record(THD *thd, List &fields, List &values, + bool ignore_errors); +bool fill_record(THD *thd, Field **field, List &values, + bool ignore_errors); OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild); inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f2c235cac99..4a8c12b5d76 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1145,7 +1145,8 @@ static void server_init(void) WSADATA WsaData; if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData)) { - my_error(ER_WSAS_FAILED, MYF(0)); + /* errors are not read yet, so we use test here */ + my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0)); unireg_abort(1); } } diff --git a/sql/parse_file.cc b/sql/parse_file.cc index f548c16d808..61b5b301503 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -350,7 +350,8 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, if (stat_info.st_size > INT_MAX-1) { - my_error(ER_FPARSER_TOO_BIG_FILE, MYF(0), file_name->str); + my_printf_error(ER_FPARSER_TOO_BIG_FILE, + ER(ER_FPARSER_TOO_BIG_FILE), MYF(0), file_name->str); DBUG_RETURN(0); } @@ -412,7 +413,8 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, frm_error: if (bad_format_errors) { - my_error(ER_FPARSER_BAD_HEADER, MYF(0), file_name->str); + my_printf_error(ER_FPARSER_BAD_HEADER, ER(ER_FPARSER_BAD_HEADER), MYF(0), + file_name->str); DBUG_RETURN(0); } else @@ -627,7 +629,8 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, // it is comment if (!(ptr= strchr(ptr, '\n'))) { - my_error(ER_FPARSER_EOF_IN_COMMENT, MYF(0), line); + my_printf_error(ER_FPARSER_EOF_IN_COMMENT, + ER(ER_FPARSER_EOF_IN_COMMENT), MYF(0), line); DBUG_RETURN(TRUE); } ptr++; @@ -669,8 +672,9 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, (LEX_STRING *)(base + parameter->offset)))) { - my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, + ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } break; @@ -681,8 +685,9 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, (LEX_STRING *) (base + parameter->offset)))) { - my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, + ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } break; @@ -691,8 +696,9 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, case FILE_OPTIONS_REV: if (!(eol= strchr(ptr, '\n'))) { - my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, + ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } { @@ -709,8 +715,9 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, /* yyyy-mm-dd HH:MM:SS = 19(PARSE_FILE_TIMESTAMPLENGTH) characters */ if (ptr[PARSE_FILE_TIMESTAMPLENGTH] != '\n') { - my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, + ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } memcpy(val->str, ptr, PARSE_FILE_TIMESTAMPLENGTH); @@ -763,8 +770,9 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, break; list_err_w_message: - my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), - parameter->name.str, line); + my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, + ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), + parameter->name.str, line); list_err: if (change_mem) my_pthread_setspecific_ptr(THR_MALLOC, sql_mem); @@ -779,8 +787,9 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, // skip unknown parameter if (!(ptr= strchr(ptr, '\n'))) { - my_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, MYF(0), - line); + my_printf_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, + ER(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER), MYF(0), + line); DBUG_RETURN(TRUE); } ptr++; diff --git a/sql/protocol.cc b/sql/protocol.cc index b8414e45c97..710618b0647 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -611,7 +611,8 @@ bool Protocol::send_fields(List *list, int flags) DBUG_RETURN(prepare_for_send(list)); err: - my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */ + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), + MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } diff --git a/sql/protocol_cursor.cc b/sql/protocol_cursor.cc index 0954bb5466f..3106420a0e5 100644 --- a/sql/protocol_cursor.cc +++ b/sql/protocol_cursor.cc @@ -85,7 +85,8 @@ bool Protocol_cursor::send_fields(List *list, int flags) DBUG_RETURN(FALSE); err: - my_error(ER_OUT_OF_RESOURCES, MYF(0)); /* purecov: inspected */ + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), + MYF(0)); /* purecov: inspected */ DBUG_RETURN(TRUE); /* purecov: inspected */ } diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 6ba1ce6267f..0d6ed33e952 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -451,8 +451,9 @@ bool show_new_master(THD* thd) if (translate_master(thd, lex_mi, errmsg)) { if (errmsg[0]) - my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), - "SHOW NEW MASTER", errmsg); + my_printf_error(ER_ERROR_WHEN_EXECUTING_COMMAND, + ER(ER_ERROR_WHEN_EXECUTING_COMMAND), MYF(0), + "SHOW NEW MASTER", errmsg); DBUG_RETURN(TRUE); } else @@ -783,7 +784,7 @@ bool load_master_data(THD* thd) (error=terminate_slave_threads(active_mi,restart_thread_mask, 1 /*skip lock*/))) { - my_error(error, MYF(0)); + my_message(error, ER(error), MYF(0)); unlock_slave_threads(active_mi); pthread_mutex_unlock(&LOCK_active_mi); return TRUE; @@ -791,7 +792,8 @@ bool load_master_data(THD* thd) if (connect_to_master(thd, &mysql, active_mi)) { - my_error(error= ER_CONNECT_TO_MASTER, MYF(0), mysql_error(&mysql)); + my_printf_error(error= ER_CONNECT_TO_MASTER, + ER(ER_CONNECT_TO_MASTER), MYF(0), mysql_error(&mysql)); goto err; } @@ -803,7 +805,8 @@ bool load_master_data(THD* thd) if (mysql_real_query(&mysql, "SHOW DATABASES", 14) || !(db_res = mysql_store_result(&mysql))) { - my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); + my_printf_error(error = ER_QUERY_ON_MASTER, + ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); goto err; } @@ -816,7 +819,7 @@ bool load_master_data(THD* thd) if (!(table_res = (MYSQL_RES**)thd->alloc(num_dbs * sizeof(MYSQL_RES*)))) { - my_error(error = ER_OUTOFMEMORY, MYF(0)); + my_message(error = ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0)); goto err; } @@ -830,7 +833,8 @@ bool load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW MASTER STATUS",18) || !(master_status_res = mysql_store_result(&mysql))) { - my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); + my_printf_error(error = ER_QUERY_ON_MASTER, + ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); goto err; } @@ -883,7 +887,8 @@ bool load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW TABLES", 11) || !(*cur_table_res = mysql_store_result(&mysql))) { - my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); + my_printf_error(error = ER_QUERY_ON_MASTER, + ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; } @@ -921,7 +926,7 @@ bool load_master_data(THD* thd) if (init_master_info(active_mi, master_info_file, relay_log_info_file, 0)) - my_error(ER_MASTER_INFO, MYF(0)); + my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); strmake(active_mi->master_log_name, row[0], sizeof(active_mi->master_log_name)); active_mi->master_log_pos= my_strtoll10(row[1], (char**) 0, &error); @@ -940,7 +945,8 @@ bool load_master_data(THD* thd) if (mysql_real_query(&mysql, "UNLOCK TABLES", 13)) { - my_error(error = ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); + my_printf_error(error = ER_QUERY_ON_MASTER, + ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); goto err; } } @@ -949,7 +955,7 @@ bool load_master_data(THD* thd) 0 /* not only reset, but also reinit */, &errmsg)) { - my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); + my_printf_error(ER_RELAY_LOG_FAIL, ER(ER_RELAY_LOG_FAIL), MYF(0), errmsg); unlock_slave_threads(active_mi); pthread_mutex_unlock(&LOCK_active_mi); return TRUE; diff --git a/sql/set_var.cc b/sql/set_var.cc index 8195792419e..59ca464182d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -884,8 +884,8 @@ bool sys_var_str::check(THD *thd, set_var *var) return 0; if ((res=(*check_func)(thd, var)) < 0) - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, - var->value->str_value.ptr()); + my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), + name, var->value->str_value.ptr()); return res; } @@ -1159,7 +1159,8 @@ static int check_max_delayed_threads(THD *thd, set_var *var) val != (longlong) global_system_variables.max_insert_delayed_threads) { char buf[64]; - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf)); + my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), + MYF(0), var->var->name, llstr(val, buf)); return 1; } return 0; @@ -1457,7 +1458,8 @@ bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names) return 0; err: - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value); + my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), + name, value); return 1; } @@ -1496,7 +1498,8 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) return 0; err: - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff); + my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), + MYF(0), name, buff); return 1; } @@ -1520,8 +1523,9 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) { if (var_type != OPT_DEFAULT) { - my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), - name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); + my_printf_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, + ER(ER_INCORRECT_GLOBAL_LOCAL_VAR), MYF(0), + name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); return 0; } /* As there was no local variable, return the global value */ @@ -1564,7 +1568,8 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) return tmp; } default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), name); + my_printf_error(ER_VAR_CANT_BE_READ, ER(ER_VAR_CANT_BE_READ), MYF(0), + name); } return 0; } @@ -1676,7 +1681,8 @@ bool sys_var_thd_date_time_format::check(THD *thd, set_var *var) if (!(format= date_time_format_make(date_time_type, res->ptr(), res->length()))) { - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr()); + my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), + name, res->c_ptr()); return 1; } @@ -1774,12 +1780,14 @@ bool sys_var_collation::check(THD *thd, set_var *var) String str(buff,sizeof(buff), system_charset_info), *res; if (!(res=var->value->val_str(&str))) { - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL"); + my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), + MYF(0), name, "NULL"); return 1; } if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0)))) { - my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr()); + my_printf_error(ER_UNKNOWN_COLLATION, ER(ER_UNKNOWN_COLLATION), MYF(0), + res->c_ptr()); return 1; } } @@ -1789,7 +1797,8 @@ bool sys_var_collation::check(THD *thd, set_var *var) { char buf[20]; int10_to_str((int) var->value->val_int(), buf, -10); - my_error(ER_UNKNOWN_COLLATION, MYF(0), buf); + my_printf_error(ER_UNKNOWN_COLLATION, ER(ER_UNKNOWN_COLLATION), MYF(0), + buf); return 1; } } @@ -1810,7 +1819,8 @@ bool sys_var_character_set::check(THD *thd, set_var *var) { if (!nullable) { - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL"); + my_printf_error(ER_WRONG_VALUE_FOR_VAR, + ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), name, "NULL"); return 1; } tmp= NULL; @@ -1818,7 +1828,8 @@ bool sys_var_character_set::check(THD *thd, set_var *var) else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) && !(tmp=get_old_charset_by_name(res->c_ptr()))) { - my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); + my_printf_error(ER_UNKNOWN_CHARACTER_SET, ER(ER_UNKNOWN_CHARACTER_SET), + MYF(0), res->c_ptr()); return 1; } } @@ -2336,7 +2347,7 @@ bool sys_var_slave_skip_counter::check(THD *thd, set_var *var) pthread_mutex_lock(&active_mi->rli.run_lock); if (active_mi->rli.slave_running) { - my_error(ER_SLAVE_MUST_STOP, MYF(0)); + my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); result=1; } pthread_mutex_unlock(&active_mi->rli.run_lock); @@ -2415,7 +2426,8 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) if (!(var->save_result.time_zone= my_tz_find(res, thd->lex->time_zone_tables_used))) { - my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL"); + my_printf_error(ER_UNKNOWN_TIME_ZONE, ER(ER_UNKNOWN_TIME_ZONE), MYF(0), + res ? res->c_ptr() : "NULL"); return 1; } return 0; @@ -2697,7 +2709,8 @@ sys_var *find_sys_var(const char *str, uint length) length ? length : strlen(str)); if (!var) - my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str); + my_printf_error(ER_UNKNOWN_SYSTEM_VARIABLE, ER(ER_UNKNOWN_SYSTEM_VARIABLE), + MYF(0), (char*) str); return var; } @@ -2783,9 +2796,8 @@ int set_var::check(THD *thd) { if (var->check_type(type)) { - my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE, - MYF(0), - var->name); + int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE; + my_printf_error(err, ER(err), MYF(0), var->name); return -1; } if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))) @@ -2795,7 +2807,7 @@ int set_var::check(THD *thd) { if (var->check_default(type)) { - my_error(ER_NO_DEFAULT, MYF(0), var->name); + my_printf_error(ER_NO_DEFAULT, ER(ER_NO_DEFAULT), MYF(0), var->name); return -1; } return 0; @@ -2805,7 +2817,8 @@ int set_var::check(THD *thd) return -1; if (var->check_update_type(value->result_type())) { - my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name); + my_printf_error(ER_WRONG_TYPE_FOR_VAR, ER(ER_WRONG_TYPE_FOR_VAR), MYF(0), + var->name); return -1; } return var->check(thd, this) ? -1 : 0; @@ -2828,9 +2841,8 @@ int set_var::light_check(THD *thd) { if (var->check_type(type)) { - my_error(type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE, - MYF(0), - var->name); + int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE; + my_printf_error(err, ER(err), MYF(0), var->name); return -1; } if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)) @@ -2896,7 +2908,7 @@ int set_var_user::update(THD *thd) if (user_var_item->update()) { /* Give an error if it's not given already */ - my_error(ER_SET_CONSTANTS_ONLY, MYF(0)); + my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0)); return -1; } return 0; @@ -2957,8 +2969,9 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var) value= "unknown"; err: - my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value); - return 1; + my_printf_error(ER_UNKNOWN_STORAGE_ENGINE, ER(ER_UNKNOWN_STORAGE_ENGINE), + MYF(0), value); + return 1; } diff --git a/sql/slave.cc b/sql/slave.cc index 2ed554e65c8..68e51eacc1e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1489,7 +1489,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, packet_len= my_net_read(net); // read create table statement if (packet_len == packet_error) { - my_error(ER_MASTER_NET_READ, MYF(0)); + my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0)); DBUG_RETURN(1); } if (net->read_pos[0] == 255) // error from master @@ -1498,7 +1498,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, err_msg= (char*) net->read_pos + ((mysql->server_capabilities & CLIENT_PROTOCOL_41) ? 3+SQLSTATE_LENGTH+1 : 3); - my_error(ER_MASTER, MYF(0), err_msg); + my_printf_error(ER_MASTER, ER(ER_MASTER), MYF(0), err_msg); DBUG_RETURN(1); } thd->command = COM_TABLE_DUMP; @@ -1507,7 +1507,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, if (!(query = thd->strmake((char*) net->read_pos, packet_len))) { sql_print_error("create_table_from_dump: out of memory"); - my_error(ER_GET_ERRNO, MYF(0), "Out of memory"); + my_message(ER_GET_ERRNO, "Out of memory", MYF(0)); DBUG_RETURN(1); } thd->query= query; @@ -1552,7 +1552,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, /* Copy the data file */ if (file->net_read_dump(net)) { - my_error(ER_MASTER_NET_READ, MYF(0)); + my_message(ER_MASTER_NET_READ, ER(ER_MASTER_NET_READ), MYF(0)); sql_print_error("create_table_from_dump: failed in\ handler::net_read_dump()"); goto err; @@ -1572,7 +1572,8 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, error=file->repair(thd,&check_opt) != 0; thd->net.vio = save_vio; if (error) - my_error(ER_INDEX_REBUILD, MYF(0), tables.table->real_name); + my_printf_error(ER_INDEX_REBUILD, ER(ER_INDEX_REBUILD), MYF(0), + tables.table->real_name); err: close_thread_tables(thd); @@ -1599,7 +1600,8 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, } if (connect_to_master(thd, mysql, mi)) { - my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql)); + my_printf_error(ER_CONNECT_TO_MASTER, ER(ER_CONNECT_TO_MASTER), MYF(0), + mysql_error(mysql)); mysql_close(mysql); DBUG_RETURN(1); } diff --git a/sql/sp.cc b/sql/sp.cc index db03900f44a..4f937e0ad8e 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1001,7 +1001,8 @@ sp_cache_functions(THD *thd, LEX *lex) { delete newlex; thd->lex= oldlex; - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", ls->str); + my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), + "FUNCTION", ls->str); ret= 1; break; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 30c7524032f..9ca986a0f6a 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -623,7 +623,7 @@ sp_head::execute_procedure(THD *thd, List *args) if (args->elements != params) { - my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), + my_printf_error(ER_SP_WRONG_NO_OF_ARGS, ER(ER_SP_WRONG_NO_OF_ARGS), MYF(0), "PROCEDURE", m_name.str, params, args->elements); DBUG_RETURN(-1); } @@ -893,7 +893,8 @@ sp_head::check_backpatch(THD *thd) { if (bp->lab->type == SP_LAB_REF) { - my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name); + my_printf_error(ER_SP_LILABEL_MISMATCH, ER(ER_SP_LILABEL_MISMATCH), + MYF(0), "GOTO", bp->lab->name); return -1; } } @@ -1786,7 +1787,7 @@ sp_instr_error::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_error::execute"); - my_error(m_errcode, MYF(0)); + my_message(m_errcode, ER(m_errcode), MYF(0)); *nextp= m_ip+1; DBUG_RETURN(-1); } diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index db298974c45..609882b84c6 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -153,7 +153,8 @@ sp_cursor::pre_open(THD *thd) { if (m_isopen) { - my_error(ER_SP_CURSOR_ALREADY_OPEN, MYF(0)); + my_message(ER_SP_CURSOR_ALREADY_OPEN, ER(ER_SP_CURSOR_ALREADY_OPEN), + MYF(0)); return NULL; } @@ -187,7 +188,7 @@ sp_cursor::close(THD *thd) { if (! m_isopen) { - my_error(ER_SP_CURSOR_NOT_OPEN, MYF(0)); + my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0)); return -1; } destroy(); @@ -217,12 +218,12 @@ sp_cursor::fetch(THD *thd, List *vars) if (! m_isopen) { - my_error(ER_SP_CURSOR_NOT_OPEN, MYF(0)); + my_message(ER_SP_CURSOR_NOT_OPEN, ER(ER_SP_CURSOR_NOT_OPEN), MYF(0)); return -1; } if (m_current_row == NULL) { - my_error(ER_SP_FETCH_NO_DATA, MYF(0)); + my_message(ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA), MYF(0)); return -1; } @@ -234,7 +235,8 @@ sp_cursor::fetch(THD *thd, List *vars) if (fldcount >= m_prot->get_field_count()) { - my_error(ER_SP_WRONG_NO_OF_FETCH_ARGS, MYF(0)); + my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS, + ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0)); return -1; } s= row[fldcount]; @@ -260,7 +262,8 @@ sp_cursor::fetch(THD *thd, List *vars) } if (fldcount < m_prot->get_field_count()) { - my_error(ER_SP_WRONG_NO_OF_FETCH_ARGS, MYF(0)); + my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS, + ER(ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0)); return -1; } m_current_row= m_current_row->next; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 5a419746b5d..8092c93c11e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1237,7 +1237,8 @@ bool check_change_password(THD *thd, const char *host, const char *user, } if (!thd->slave_thread && !thd->user[0]) { - my_error(ER_PASSWORD_ANONYMOUS_USER, MYF(0)); + my_message(ER_PASSWORD_ANONYMOUS_USER, ER(ER_PASSWORD_ANONYMOUS_USER), + MYF(0)); return(1); } uint len=strlen(new_password); @@ -1282,7 +1283,7 @@ bool change_password(THD *thd, const char *host, const char *user, if (!(acl_user= find_acl_user(host, user))) { VOID(pthread_mutex_unlock(&acl_cache->lock)); - my_error(ER_PASSWORD_NO_MATCH, MYF(0)); + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0)); DBUG_RETURN(1); } /* update loaded acl entry: */ @@ -1467,7 +1468,8 @@ static bool update_user_table(THD *thd, const char *host, const char *user, (byte*) table->field[0]->ptr,0, HA_READ_KEY_EXACT)) { - my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */ + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), + MYF(0)); /* purecov: deadcode */ DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); @@ -1549,10 +1551,12 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (!create_user) { if (what == 'N') - my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str); + my_printf_error(ER_NONEXISTING_GRANT, ER(ER_NONEXISTING_GRANT), + MYF(0), combo.user.str, combo.host.str); else - my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0), - thd->user, thd->host_or_ip); + my_printf_error(ER_NO_PERMISSION_TO_CREATE_USER, + ER(ER_NO_PERMISSION_TO_CREATE_USER), MYF(0), + thd->user, thd->host_or_ip); goto end; } old_row_exists = 0; @@ -1717,7 +1721,7 @@ static int replace_db_table(TABLE *table, const char *db, /* Check if there is such a user in user table in memory? */ if (!find_acl_user(combo.host.str,combo.user.str)) { - my_error(ER_PASSWORD_NO_MATCH,MYF(0)); + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0)); DBUG_RETURN(-1); } @@ -1729,7 +1733,8 @@ static int replace_db_table(TABLE *table, const char *db, { if (what == 'N') { // no row, no revoke - my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str); + my_printf_error(ER_NONEXISTING_GRANT, ER(ER_NONEXISTING_GRANT), MYF(0), + combo.user.str, combo.host.str); goto abort; } old_row_exists = 0; @@ -2036,8 +2041,10 @@ static int replace_column_table(GRANT_TABLE *g_t, { if (revoke_grant) { - my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), - combo.user.str, combo.host.str, table_name); /* purecov: inspected */ + my_printf_error(ER_NONEXISTING_TABLE_GRANT, + ER(ER_NONEXISTING_TABLE_GRANT), MYF(0), + combo.user.str, combo.host.str, + table_name); /* purecov: inspected */ result= -1; /* purecov: inspected */ continue; /* purecov: inspected */ } @@ -2180,7 +2187,8 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, */ if (!find_acl_user(combo.host.str,combo.user.str)) { - my_error(ER_PASSWORD_NO_MATCH,MYF(0)); /* purecov: deadcode */ + my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), + MYF(0)); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ } @@ -2202,9 +2210,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, */ if (revoke_grant) { // no row, no revoke - my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), - combo.user.str, combo.host.str, - table_name); /* purecov: deadcode */ + my_printf_error(ER_NONEXISTING_TABLE_GRANT, + ER(ER_NONEXISTING_TABLE_GRANT), MYF(0), + combo.user.str, combo.host.str, + table_name); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ } old_row_exists = 0; @@ -2311,7 +2320,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, } if (rights & ~TABLE_ACLS) { - my_error(ER_ILLEGAL_GRANT_FOR_TABLE,MYF(0)); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), + MYF(0)); DBUG_RETURN(TRUE); } @@ -2332,8 +2342,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, column->column.length(), 0, 0, 0, 0, &unused_field_idx)) { - my_error(ER_BAD_FIELD_ERROR, MYF(0), - column->column.c_ptr(), table_list->alias); + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + column->column.c_ptr(), table_list->alias); DBUG_RETURN(TRUE); } column_priv|= column->rights; @@ -2348,7 +2358,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, fn_format(buf,buf,"","",4+16+32); if (access(buf,F_OK)) { - my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); + my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), + table_list->db, table_list->alias); DBUG_RETURN(TRUE); } } @@ -2406,7 +2417,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (Str->host.length > HOSTNAME_LENGTH || Str->user.length > USERNAME_LENGTH) { - my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); + my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), + MYF(0)); result= TRUE; continue; } @@ -2435,8 +2447,9 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, { if (revoke_grant) { - my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), - Str->user.str, Str->host.str, table_list->real_name); + my_printf_error(ER_NONEXISTING_TABLE_GRANT, + ER(ER_NONEXISTING_TABLE_GRANT), MYF(0), + Str->user.str, Str->host.str, table_list->real_name); result= TRUE; continue; } @@ -2581,7 +2594,8 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (Str->host.length > HOSTNAME_LENGTH || Str->user.length > USERNAME_LENGTH) { - my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); + my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), + MYF(0)); result= -1; continue; } @@ -2876,11 +2890,12 @@ err: command= "create view"; else if (want_access & SHOW_VIEW_ACL) command= "show create view"; - my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), - command, - thd->priv_user, - thd->host_or_ip, - table ? table->real_name : "unknown"); + my_printf_error(ER_TABLEACCESS_DENIED_ERROR, + ER(ER_TABLEACCESS_DENIED_ERROR), MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + table ? table->real_name : "unknown"); } DBUG_RETURN(1); } @@ -3168,7 +3183,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) if (lex_user->host.length > HOSTNAME_LENGTH || lex_user->user.length > USERNAME_LENGTH) { - my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); + my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), + MYF(0)); DBUG_RETURN(TRUE); } @@ -3186,8 +3202,9 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) } if (counter == acl_users.elements) { - my_error(ER_NONEXISTING_GRANT, MYF(0), - lex_user->user.str, lex_user->host.str); + my_printf_error(ER_NONEXISTING_GRANT, + ER(ER_NONEXISTING_GRANT), MYF(0), + lex_user->user.str, lex_user->host.str); DBUG_RETURN(TRUE); } @@ -3700,7 +3717,7 @@ bool mysql_drop_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_error(ER_DROP_USER, MYF(0)); + my_message(ER_DROP_USER, ER(ER_DROP_USER), MYF(0)); DBUG_RETURN(result); } @@ -3804,7 +3821,7 @@ bool mysql_revoke_all(THD *thd, List &list) /* when this code is deleted, the error slot (error 1268) can be reused, as this error code was not present in any MySQL release */ if (result) - my_error(ER_REVOKE_GRANTS, MYF(0)); + my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); DBUG_RETURN(result); } diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 3f75dadb6f0..c83bd978bfe 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -81,14 +81,18 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val() < 0) { delete pc; - my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); + my_printf_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, + ER(ER_WRONG_PARAMETERS_TO_PROCEDURE), MYF(0), + proc_name); DBUG_RETURN(0); } pc->max_tree_elements = (uint) (*param->item)->val_int(); param = param->next; if (param->next) // no third parameter possible { - my_error(ER_WRONG_PARAMCOUNT_TO_PROCEDURE, MYF(0), proc_name); + my_printf_error(ER_WRONG_PARAMCOUNT_TO_PROCEDURE, + ER(ER_WRONG_PARAMCOUNT_TO_PROCEDURE), MYF(0), + proc_name); DBUG_RETURN(0); } // second parameter @@ -96,7 +100,9 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val() < 0) { delete pc; - my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); + my_printf_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, + ER(ER_WRONG_PARAMETERS_TO_PROCEDURE), MYF(0), + proc_name); DBUG_RETURN(0); } pc->max_treemem = (uint) (*param->item)->val_int(); @@ -105,7 +111,8 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val() < 0) { delete pc; - my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); + my_printf_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, + ER(ER_WRONG_PARAMETERS_TO_PROCEDURE), MYF(0), proc_name); DBUG_RETURN(0); } // if only one parameter was given, it will be the value of max_tree_elements diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1f52c532737..a6a7e99ecec 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1224,7 +1224,8 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh) next=table->next; if (!tables || (!db_stat && reopen_table(table,1))) { - my_error(ER_CANT_REOPEN_TABLE,MYF(0),table->table_name); + my_printf_error(ER_CANT_REOPEN_TABLE, ER(ER_CANT_REOPEN_TABLE), + MYF(0),table->table_name); VOID(hash_delete(&open_cache,(byte*) table)); error=1; } @@ -1509,7 +1510,8 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, { /* Give right error message */ thd->clear_error(); - my_error(ER_NOT_KEYFILE, MYF(0), name, my_errno); + my_printf_error(ER_NOT_KEYFILE, ER(ER_NOT_KEYFILE), MYF(0), + name, my_errno); sql_print_error("Error: Couldn't repair table: %s.%s",db,name); if (entry->file) closefrm(entry); @@ -1574,7 +1576,8 @@ err: { TABLE_LIST * view= table_desc->belong_to_view; thd->clear_error(); - my_error(ER_VIEW_INVALID, MYF(0), view->view_db.str, view->view_name.str); + my_printf_error(ER_VIEW_INVALID, ER(ER_VIEW_INVALID), MYF(0), + view->view_db.str, view->view_name.str); } DBUG_RETURN(1); } @@ -2738,8 +2741,9 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, (pos= find_type(&table->keynames, name->ptr(), name->length(), 1)) <= 0) { - my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(), - table->real_name); + my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, + ER(ER_KEY_COLUMN_DOES_NOT_EXITS), MYF(0), + name->c_ptr(), table->real_name); map->set_all(); return 1; } @@ -2954,9 +2958,10 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, DBUG_RETURN(0); if (!table_name) - my_error(ER_NO_TABLES_USED, MYF(0)); + my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0)); else - my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name); + my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), + table_name); err: DBUG_RETURN(1); @@ -3176,8 +3181,25 @@ err_no_arena: ** Returns : 1 if some field has wrong type ******************************************************************************/ -int -fill_record(List &fields,List &values, bool ignore_errors) + +/* + Fill fields with given items. + + SYNOPSIS + fill_record() + thd thread handler + fields Item_fields list to be filled + values values to fill with + ignore_errors TRUE if we should ignore errors + + RETURN + FALSE OK + TRUE error occured +*/ + +bool +fill_record(THD * thd, List &fields, List &values, + bool ignore_errors) { List_iterator_fast f(fields),v(values); Item *value; @@ -3192,14 +3214,32 @@ fill_record(List &fields,List &values, bool ignore_errors) if (rfield == table->next_number_field) table->auto_increment_field_not_null= TRUE; if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors) - DBUG_RETURN(1); + { + my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0)); + DBUG_RETURN(TRUE); + } } - DBUG_RETURN(0); + DBUG_RETURN(thd->net.report_error); } -int -fill_record(Field **ptr,List &values, bool ignore_errors) +/* + Fill field buffer with values from Field list + + SYNOPSIS + fill_record() + thd thread handler + ptr pointer on pointer to record + values list of fields + ignore_errors TRUE if we should ignore errors + + RETURN + FALSE OK + TRUE error occured +*/ + +bool +fill_record(THD *thd, Field **ptr, List &values, bool ignore_errors) { List_iterator_fast v(values); Item *value; @@ -3213,9 +3253,12 @@ fill_record(Field **ptr,List &values, bool ignore_errors) if (field == table->next_number_field) table->auto_increment_field_not_null= TRUE; if ((value->save_in_field(field, 0) < 0) && !ignore_errors) - DBUG_RETURN(1); + { + my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0)); + DBUG_RETURN(TRUE); + } } - DBUG_RETURN(0); + DBUG_RETURN(thd->net.report_error); } @@ -3439,7 +3482,8 @@ open_new_frm(const char *path, const char *alias, { if (table_desc == 0 || table_desc->required_type == FRMTYPE_TABLE) { - my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE"); + my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), + db, table_name, "BASE TABLE"); goto err; } if (mysql_make_view(parser, table_desc)) @@ -3448,7 +3492,8 @@ open_new_frm(const char *path, const char *alias, else { /* only VIEWs are supported now */ - my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), path, parser->type()->str); + my_printf_error(ER_FRM_UNKNOWN_TYPE, ER(ER_FRM_UNKNOWN_TYPE), MYF(0), + path, parser->type()->str); goto err; } DBUG_RETURN(0); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a543222a4a1..966b7de6712 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -695,8 +695,8 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) key_length + 1); if (!new_table) { - my_error(EE_OUTOFMEMORY, MYF(ME_BELL), - ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); + my_printf_error(EE_OUTOFMEMORY, ER(EE_OUTOFMEMORY), MYF(ME_BELL), + ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); killed= KILL_CONNECTION; return 0; } @@ -953,7 +953,8 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, (void) fn_format(path, exchange->file_name, path, "", option); if (!access(path, F_OK)) { - my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); + my_printf_error(ER_FILE_EXISTS_ERROR, ER(ER_FILE_EXISTS_ERROR), MYF(0), + exchange->file_name); return -1; } /* Create the file world readable */ @@ -1184,7 +1185,7 @@ bool select_dump::send_data(List &items) } if (row_count++ > 1) { - my_error(ER_TOO_MANY_ROWS, MYF(0)); + my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); goto err; } while ((item=li++)) @@ -1197,7 +1198,8 @@ bool select_dump::send_data(List &items) } else if (my_b_write(&cache,(byte*) res->ptr(),res->length())) { - my_error(ER_ERROR_ON_WRITE,MYF(0), path, my_errno); + my_printf_error(ER_ERROR_ON_WRITE, ER(ER_ERROR_ON_WRITE), MYF(0), + path, my_errno); goto err; } } @@ -1356,7 +1358,8 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) if (var_list.elements != list.elements) { - my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); + my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, + ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0)); return 1; } while ((item=li++)) @@ -1626,7 +1629,7 @@ bool select_dumpvar::send_data(List &items) } if (row_count++) { - my_error(ER_TOO_MANY_ROWS, MYF(0)); + my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); DBUG_RETURN(1); } while ((zz=my_li++) && (item=it++)) diff --git a/sql/sql_class.h b/sql/sql_class.h index 46cf8ca4899..8de38782d3e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -41,6 +41,7 @@ enum enum_check_fields { CHECK_FIELD_IGNORE, CHECK_FIELD_WARN, CHECK_FIELD_ERROR_FOR_NULL }; extern char internal_table_name[2]; +extern const char **errmesg; /* log info errors */ #define LOG_INFO_EOF -1 @@ -1133,7 +1134,8 @@ public: } inline void send_kill_message() const { - my_error(killed_errno(), MYF(0)); + int err= killed_errno(); + my_message(err, ER(err), MYF(0)); } /* return TRUE if we will abort query if we make a warning now */ inline bool really_abort_on_warning() diff --git a/sql/sql_db.cc b/sql/sql_db.cc index df3c27b9b72..e3a19ea32a7 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -413,7 +413,8 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, { if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) { - my_error(ER_DB_CREATE_EXISTS,MYF(0),db); + my_printf_error(ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), MYF(0), + db); error= -1; goto exit; } @@ -423,12 +424,13 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, { if (my_errno != ENOENT) { - my_error(EE_STAT, MYF(0),path,my_errno); + my_printf_error(EE_STAT, ER(EE_STAT), MYF(0), path, my_errno); goto exit; } if (my_mkdir(path,0777,MYF(0)) < 0) { - my_error(ER_CANT_CREATE_DB,MYF(0),db,my_errno); + my_printf_error(ER_CANT_CREATE_DB, ER(ER_CANT_CREATE_DB), + MYF(0), db, my_errno); error= -1; goto exit; } @@ -582,7 +584,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (!if_exists) { error= -1; - my_error(ER_DB_DROP_EXISTS,MYF(0),db); + my_printf_error(ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), MYF(0), db); goto exit; } else @@ -806,7 +808,8 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, */ if (found_other_files) { - my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST); + my_printf_error(ER_DB_DROP_RMDIR, ER(ER_DB_DROP_RMDIR), MYF(0), + org_path, EEXIST); DBUG_RETURN(-1); } else @@ -869,7 +872,8 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) *--pos=0; if (rmdir(path) < 0 && send_error) { - my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno); + my_printf_error(ER_DB_DROP_RMDIR, ER(ER_DB_DROP_RMDIR), MYF(0), + path, errno); DBUG_RETURN(-1); } DBUG_RETURN(0); @@ -985,12 +989,13 @@ bool mysql_change_db(THD *thd, const char *name) if (!dbname || !(db_length= strlen(dbname))) { x_free(dbname); /* purecov: inspected */ - my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: inspected */ + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), + MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (check_db_name(dbname)) { - my_error(ER_WRONG_DB_NAME, MYF(0), dbname); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), dbname); x_free(dbname); DBUG_RETURN(1); } @@ -1003,10 +1008,11 @@ bool mysql_change_db(THD *thd, const char *name) thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), - thd->priv_user, - thd->priv_host, - dbname); + my_printf_error(ER_DBACCESS_DENIED_ERROR, + ER(ER_DBACCESS_DENIED_ERROR), MYF(0), + thd->priv_user, + thd->priv_host, + dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->priv_host, @@ -1021,7 +1027,7 @@ bool mysql_change_db(THD *thd, const char *name) path[length-1]=0; // remove ending '\' if (access(path,F_OK)) { - my_error(ER_BAD_DB_ERROR, MYF(0), dbname); + my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 54c6cd1ebc5..26b37efb773 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -55,7 +55,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, safe_update=test(thd->options & OPTION_SAFE_UPDATES); if (safe_update && const_cond) { - my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); DBUG_RETURN(TRUE); } @@ -103,7 +104,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { delete select; free_underlaid_joins(thd, &thd->lex->select_lex); - my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); DBUG_RETURN(TRUE); } } @@ -259,7 +261,7 @@ cleanup: send_ok(thd,deleted); DBUG_PRINT("info",("%d records deleted",deleted)); } - DBUG_RETURN(FALSE); + DBUG_RETURN(error >= 0 || thd->net.report_error); } @@ -287,12 +289,14 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) DBUG_RETURN(TRUE); if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); + my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), MYF(0), + table_list->alias, "DELETE"); DBUG_RETURN(TRUE); } if (unique_table(table_list, table_list->next_independent())) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); + my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), MYF(0), + table_list->real_name); DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, conds); @@ -349,8 +353,8 @@ bool mysql_multi_delete_prepare(THD *thd) if (!target_tbl->correspondent_table->updatable || check_key_in_view(thd, target_tbl->correspondent_table)) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), target_tbl->real_name, - "DELETE"); + my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), + MYF(0), target_tbl->real_name, "DELETE"); DBUG_RETURN(TRUE); } /* @@ -367,8 +371,8 @@ bool mysql_multi_delete_prepare(THD *thd) un->check_updateable(target_tbl->correspondent_table->db, target_tbl->correspondent_table->real_name)) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), - target_tbl->correspondent_table->real_name); + my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), + MYF(0), target_tbl->correspondent_table->real_name); DBUG_RETURN(TRUE); } } @@ -729,8 +733,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) db_type table_type; if ((table_type=get_table_type(path)) == DB_TYPE_UNKNOWN) { - my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, - table_list->real_name); + my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), + table_list->db, table_list->real_name); DBUG_RETURN(TRUE); } if (!ha_supports_generate(table_type)) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 6bab90a786e..37079fbc856 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -341,7 +341,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, break; } default: - my_error(ER_ILLEGAL_HA, MYF(0)); + my_message(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0)); goto err; } @@ -370,7 +370,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, if (item->send(thd->protocol, &buffer)) { protocol->free(); // Free used - my_error(ER_OUT_OF_RESOURCES,MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); goto err; } } diff --git a/sql/sql_help.cc b/sql/sql_help.cc index d108f6f69b4..cfa3325be8a 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -276,7 +276,7 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, (iindex_relations= find_type((char*) primary_key_name, &relations->keynames, 1+2)-1)<0) { - my_error(ER_CORRUPT_HELP_DB, 0); + my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0)); DBUG_RETURN(-1); } rtopic_id= find_fields[help_relation_help_topic_id].field; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 81f80378763..4ba09e12811 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -100,7 +100,8 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, if (check_unique && thd->dupp_field) { - my_error(ER_FIELD_SPECIFIED_TWICE,MYF(0), thd->dupp_field->field_name); + my_printf_error(ER_FIELD_SPECIFIED_TWICE, ER(ER_FIELD_SPECIFIED_TWICE), + MYF(0), thd->dupp_field->field_name); return -1; } if (table->timestamp_field && // Don't set timestamp if used @@ -291,7 +292,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, if (fields.elements || !value_count) { restore_record(table,default_values); // Get empty record - if (fill_record(fields, *values, 0)|| thd->net.report_error) + if (fill_record(thd, fields, *values, 0)) { if (values_list.elements != 1 && !thd->net.report_error) { @@ -299,14 +300,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, continue; } /* - Field::store methods can't send errors - TODO: set thd->abort_on_warning if values_list.elements == 1 and check that all items return warning in case of problem with storing field. */ - if (!thd->net.report_error) - my_error(ER_UNKNOWN_ERROR, MYF(0)); error=1; break; } @@ -317,16 +314,13 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, restore_record(table,default_values); // Get empty record else table->record[0][0]=table->default_values[0]; // Fix delete marker - if (fill_record(table->field,*values, 0) || thd->net.report_error) + if (fill_record(thd, table->field, *values, 0)) { if (values_list.elements != 1 && ! thd->net.report_error) { info.records++; continue; } - /* Field::store methods can't send errors */ - if (!thd->net.report_error) - my_error(ER_UNKNOWN_ERROR, MYF(0)); error=1; break; } @@ -608,7 +602,8 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, (insert_into_view && check_view_insertability(table_list, thd->query_id))) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT"); + my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), + MYF(0), table_list->alias, "INSERT"); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -655,7 +650,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, if (unique_table(table_list, table_list->next_independent())) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); + my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), + MYF(0), table_list->real_name); DBUG_RETURN(TRUE); } thd->lex->select_lex.first_execution= 0; @@ -751,13 +747,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) */ store_record(table,insert_values); restore_record(table,record[1]); - if (fill_record(*info->update_fields, *info->update_values, 0)) - { - /* Field::store methods can't send errors */ - if (!thd->net.report_error) - my_error(ER_UNKNOWN_ERROR, MYF(0)); + if (fill_record(thd, *info->update_fields, *info->update_values, 0)) goto err; - } /* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */ if (info->view && @@ -1018,7 +1009,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list) { delete tmp; thd->fatal_error(); - my_error(ER_OUT_OF_RESOURCES,MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); pthread_mutex_unlock(&LOCK_delayed_create); DBUG_RETURN(0); } @@ -1335,7 +1326,8 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) if (!(di->table->file->table_flags() & HA_CAN_INSERT_DELAYED)) { thd->fatal_error(); - my_error(ER_ILLEGAL_HA, MYF(0), di->table_list.real_name); + my_printf_error(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0), + di->table_list.real_name); goto end; } di->table->copy_blobs=1; @@ -1761,9 +1753,9 @@ bool select_insert::send_data(List &values) DBUG_RETURN(0); } if (fields->elements) - fill_record(*fields, values, 1); + fill_record(thd, *fields, values, 1); else - fill_record(table->field, values, 1); + fill_record(thd, table->field, values, 1); switch (table_list->view_check_option(thd, thd->lex->duplicates == DUP_IGNORE)) { @@ -1934,7 +1926,7 @@ bool select_create::send_data(List &values) unit->offset_limit_cnt--; return 0; } - fill_record(field, values, 1); + fill_record(thd, field, values, 1); if (thd->net.report_error || write_record(thd, table, &info)) return 1; if (table->next_number_field) // Clear for next record diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 73f99d0dd68..145ef84d57a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1273,7 +1273,7 @@ bool st_select_lex::test_limit() if (select_limit != HA_POS_ERROR) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), - "LIMIT & IN/ALL/ANY/SOME subquery"); + "LIMIT & IN/ALL/ANY/SOME subquery"); return(1); } // We need only 1 row to determinate existence diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 0be4d9ecdc1..70fa097c8f8 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -125,7 +125,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(-1); if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); + my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), + MYF(0), table_list->alias, "LOAD"); DBUG_RETURN(TRUE); } table= table_list->table; @@ -148,7 +149,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(TRUE); if (thd->dupp_field) { - my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name); + my_printf_error(ER_FIELD_SPECIFIED_TWICE, ER(ER_FIELD_SPECIFIED_TWICE), + MYF(0), thd->dupp_field->field_name); DBUG_RETURN(TRUE); } if (check_that_all_fields_are_given_values(thd, table)) @@ -222,7 +224,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ((stat_info.st_mode & S_IFREG) == S_IFREG || (stat_info.st_mode & S_IFIFO) == S_IFIFO))) { - my_error(ER_TEXTFILE_NOT_READABLE,MYF(0),name); + my_printf_error(ER_TEXTFILE_NOT_READABLE, + ER(ER_TEXTFILE_NOT_READABLE), MYF(0), name); DBUG_RETURN(TRUE); } if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) diff --git a/sql/sql_map.cc b/sql/sql_map.cc index c6637474908..917a8f2c30f 100644 --- a/sql/sql_map.cc +++ b/sql/sql_map.cc @@ -47,12 +47,13 @@ mapped_files::mapped_files(const my_string filename,byte *magic,uint magic_lengt 0L))) { error=errno; - my_error(ER_NO_FILE_MAPPING,MYF(0), (my_string) name, error); + my_printf_error(ER_NO_FILE_MAPPING, ER(ER_NO_FILE_MAPPING), MYF(0), + (my_string) name, error); } } if (map && memcmp(map,magic,magic_length)) { - my_error(ER_WRONG_MAGIC, MYF(0), name); + my_printf_error(ER_WRONG_MAGIC, ER(ER_WRONG_MAGIC), MYF(0), name); VOID(munmap(map,size)); map=0; } @@ -111,7 +112,8 @@ mapped_files *map_file(const my_string name,byte *magic,uint magic_length) { map->use_count++; if (!map->map) - my_error(ER_NO_FILE_MAPPING, MYF(0), path, map->error); + my_printf_error(ER_NO_FILE_MAPPING, ER(ER_NO_FILE_MAPPING), MYF(0), + path, map->error); } VOID(pthread_mutex_unlock(&LOCK_mapped_file)); return map; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 316f5ebdf60..5156d1e0d33 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1115,7 +1115,7 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) if (buff[length-1]!='\n' && !feof(file)) { net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS); - thd->is_fatal_error= 1; + thd->fatal_error(); break; } while (length && (my_isspace(thd->charset(), buff[length-1]) || @@ -1192,7 +1192,8 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!db || check_db_name(db)) { - my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), + db ? db : "NULL"); goto err; } if (lower_case_table_names) @@ -1396,7 +1397,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* Small check for incoming packet */ if ((uint) ((uchar*) db - net->read_pos) > packet_length) { - my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); break; } #endif @@ -1418,7 +1419,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (!(thd->user= my_strdup(user, MYF(0)))) { thd->user= save_user; - my_error(ER_OUT_OF_RESOURCES, MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); break; } @@ -1430,7 +1431,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { /* authentication failure, we shall restore old user */ if (res > 0) - my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); x_free(thd->user); thd->user= save_user; thd->priv_user= save_priv_user; @@ -1538,7 +1539,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } case COM_FIELD_LIST: // This isn't actually needed #ifdef DONT_ALLOW_SHOW_COMMANDS - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ break; #else { @@ -1551,7 +1553,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, bzero((char*) &table_list,sizeof(table_list)); if (!(table_list.db=thd->db)) { - my_error(ER_NO_DB_ERROR, MYF(0)); + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); break; } pend= strend(packet); @@ -1604,7 +1606,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), + db ? db : "NULL"); break; } if (check_access(thd,CREATE_ACL,db,0,1,0)) @@ -1621,14 +1624,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* null test to handle EOM */ if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), + MYF(0), db ? db : "NULL"); break; } if (check_access(thd,DROP_ACL,db,0,1,0)) break; if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); break; } mysql_log.write(thd,command,db); @@ -1777,7 +1782,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, send_eof(thd); break; default: - my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); break; } break; @@ -1796,7 +1801,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, case COM_DELAYED_INSERT: case COM_END: default: - my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); + my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); break; } if (thd->lock || thd->open_tables || thd->derived_tables) @@ -1808,7 +1813,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* report error issued during command execution */ if (thd->killed_errno() && !thd->net.report_error) thd->send_kill_message(); - if (thd->is_fatal_error || thd->net.report_error) + if (thd->net.report_error) net_send_error(thd); time_t start_of_query=thd->start_time; @@ -1958,7 +1963,7 @@ mysql_execute_command(THD *thd) if (all_tables_not_ok(thd, all_tables)) { /* we warn the slave SQL thread */ - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); DBUG_RETURN(0); } #ifndef TO_BE_DELETED @@ -2159,9 +2164,11 @@ mysql_execute_command(THD *thd) } else { - my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), - lex->prepared_stmt_name.length, lex->prepared_stmt_name.str, - "DEALLOCATE PREPARE"); + my_printf_error(ER_UNKNOWN_STMT_HANDLER, ER(ER_UNKNOWN_STMT_HANDLER), + MYF(0), + lex->prepared_stmt_name.length, + lex->prepared_stmt_name.str, + "DEALLOCATE PREPARE"); goto error; } break; @@ -2354,7 +2361,8 @@ mysql_execute_command(THD *thd) } if (strlen(first_table->real_name) > NAME_LEN) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->real_name); + my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), + first_table->real_name); break; } pthread_mutex_lock(&LOCK_active_mi); @@ -2425,7 +2433,8 @@ mysql_execute_command(THD *thd) if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && unique_table(create_table, select_tables)) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->real_name); + my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), + MYF(0), create_table->real_name); goto create_error; } /* If we create merge table, we have to test tables in merge, too */ @@ -2438,7 +2447,8 @@ mysql_execute_command(THD *thd) { if (unique_table(tab, select_tables)) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), tab->real_name); + my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), + MYF(0), tab->real_name); goto create_error; } } @@ -2524,7 +2534,8 @@ create_error: */ if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), + MYF(0)); goto error; } { @@ -2538,14 +2549,16 @@ create_error: case SQLCOM_ALTER_TABLE: DBUG_ASSERT(first_table == all_tables && first_table != 0); #if defined(DONT_ALLOW_SHOW_COMMANDS) - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { ulong priv=0; if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name); + my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), + lex->name); goto error; } if (!select_lex->db) @@ -2629,7 +2642,8 @@ create_error: #ifndef EMBEDDED_LIBRARY case SQLCOM_SHOW_BINLOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -2643,7 +2657,8 @@ create_error: case SQLCOM_SHOW_CREATE: DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -2841,7 +2856,8 @@ create_error: */ if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } @@ -2939,7 +2955,8 @@ create_error: break; case SQLCOM_SHOW_DATABASES: #if defined(DONT_ALLOW_SHOW_COMMANDS) - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else if ((specialflag & SPECIAL_SKIP_SHOW_DB) && @@ -2985,7 +3002,8 @@ create_error: break; case SQLCOM_SHOW_LOGS: #ifdef DONT_ALLOW_SHOW_COMMANDS - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -2998,30 +3016,33 @@ create_error: case SQLCOM_SHOW_TABLES: /* FALL THROUGH */ #ifdef DONT_ALLOW_SHOW_COMMANDS - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { char *db=select_lex->db ? select_lex->db : thd->db; if (!db) { - my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: inspected */ + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), + MYF(0)); /* purecov: inspected */ goto error; /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' if (check_db_name(db)) { - my_error(ER_WRONG_DB_NAME, MYF(0), db); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), db); goto error; } if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) goto error; /* purecov: inspected */ if (!thd->col_access && check_grant_db(thd,db)) { - my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), - thd->priv_user, - thd->priv_host, - db); + my_printf_error(ER_DBACCESS_DENIED_ERROR, + ER(ER_DBACCESS_DENIED_ERROR), MYF(0), + thd->priv_user, + thd->priv_host, + db); goto error; } /* grant is checked in mysqld_show_tables */ @@ -3047,7 +3068,8 @@ create_error: case SQLCOM_SHOW_FIELDS: DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -3068,7 +3090,8 @@ create_error: case SQLCOM_SHOW_KEYS: DBUG_ASSERT(first_table == all_tables && first_table != 0); #ifdef DONT_ALLOW_SHOW_COMMANDS - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), + MYF(0)); /* purecov: inspected */ goto error; #else { @@ -3104,7 +3127,7 @@ create_error: if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) || ! opt_local_infile) { - my_error(ER_NOT_ALLOWED_COMMAND, MYF(0)); + my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); goto error; } if (check_one_table_access(thd, privilege, all_tables)) @@ -3179,7 +3202,8 @@ create_error: char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), + lex->name); break; } /* @@ -3194,7 +3218,7 @@ create_error: (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) { - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } #endif @@ -3209,7 +3233,8 @@ create_error: char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), + lex->name); break; } /* @@ -3224,7 +3249,7 @@ create_error: (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) { - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } #endif @@ -3232,7 +3257,8 @@ create_error: break; if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } res=mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : lex->name), @@ -3243,7 +3269,8 @@ create_error: { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), + lex->name); break; } /* @@ -3258,7 +3285,7 @@ create_error: (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) { - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); break; } #endif @@ -3266,7 +3293,8 @@ create_error: break; if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } res=mysql_alter_db(thd,lex->name,&lex->create_info); @@ -3276,14 +3304,16 @@ create_error: { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), + lex->name); break; } if (check_access(thd,SELECT_ACL,lex->name,0,1,0)) break; if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); goto error; } res=mysqld_show_create_db(thd,lex->name,&lex->create_info); @@ -3297,7 +3327,8 @@ create_error: #ifdef HAVE_DLOPEN if ((sph= sp_find_function(thd, lex->spname))) { - my_error(ER_UDF_EXISTS, MYF(0), lex->spname->m_name.str); + my_printf_error(ER_UDF_EXISTS, ER(ER_UDF_EXISTS), MYF(0), + lex->spname->m_name.str); goto error; } if (!(res = mysql_create_function(thd,&lex->udf))) @@ -3405,7 +3436,8 @@ create_error: { if (lex->columns.elements) { - my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE), + MYF(0)); goto error; } else @@ -3588,7 +3620,7 @@ create_error: if (! lex->sphead->m_db.str) { - my_error(ER_NO_DB_ERROR, MYF(0)); + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); delete lex->sphead; lex->sphead= 0; goto error; @@ -3602,7 +3634,7 @@ create_error: if (udf) { - my_error(ER_UDF_EXISTS, MYF(0), name); + my_printf_error(ER_UDF_EXISTS, ER(ER_UDF_EXISTS), MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; @@ -3612,7 +3644,7 @@ create_error: if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && !lex->sphead->m_has_return) { - my_error(ER_SP_NORETURN, MYF(0), name); + my_printf_error(ER_SP_NORETURN, ER(ER_SP_NORETURN), MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; @@ -3627,19 +3659,22 @@ create_error: lex->sphead= 0; break; case SP_WRITE_ROW_FAILED: - my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name); + my_printf_error(ER_SP_ALREADY_EXISTS, ER(ER_SP_ALREADY_EXISTS), MYF(0), + SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; case SP_NO_DB_ERROR: - my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str); + my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), + lex->sphead->m_db.str); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; default: - my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); + my_printf_error(ER_SP_STORE_FAILED, ER(ER_SP_STORE_FAILED), MYF(0), + SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; @@ -3653,7 +3688,8 @@ create_error: if (!(sp= sp_find_procedure(thd, lex->spname))) { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE", + my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), + MYF(0), "PROCEDURE", lex->spname->m_qname.str); goto error; } @@ -3680,7 +3716,7 @@ create_error: { if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS)) { - my_error(ER_SP_BADSELECT, MYF(0)); + my_message(ER_SP_BADSELECT, ER(ER_SP_BADSELECT), MYF(0)); #ifndef EMBEDDED_LIBRARY thd->net.no_send_ok= nsok; #endif @@ -3751,12 +3787,12 @@ create_error: send_ok(thd); break; case SP_KEY_NOT_FOUND: - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; default: - my_error(ER_SP_CANT_ALTER, MYF(0), SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_printf_error(ER_SP_CANT_ALTER, ER(ER_SP_CANT_ALTER), MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; } break; @@ -3818,12 +3854,12 @@ create_error: send_ok(thd); break; } - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; default: - my_error(ER_SP_DROP_FAILED, MYF(0), SP_COM_STRING(lex), - lex->spname->m_qname.str); + my_printf_error(ER_SP_DROP_FAILED, ER(ER_SP_DROP_FAILED), MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; } break; @@ -3832,13 +3868,14 @@ create_error: { if (lex->spname->m_name.length > NAME_LEN) { - my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); + my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), + lex->spname->m_name.str); goto error; } if (sp_show_create_procedure(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), - SP_COM_STRING(lex), lex->spname->m_name.str); + my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } break; @@ -3847,13 +3884,14 @@ create_error: { if (lex->spname->m_name.length > NAME_LEN) { - my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); + my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), + lex->spname->m_name.str); goto error; } if (sp_show_create_function(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), - SP_COM_STRING(lex), lex->spname->m_name.str); + my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } break; @@ -4029,7 +4067,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { DBUG_PRINT("error",("No database")); if (!no_errors) - my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: tested */ + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), + MYF(0)); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -4056,10 +4095,13 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) - my_error(ER_ACCESS_DENIED_ERROR, MYF(0), - thd->priv_user, - thd->priv_host, - thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */ + my_printf_error(ER_ACCESS_DENIED_ERROR, + ER(ER_ACCESS_DENIED_ERROR), MYF(0), + thd->priv_user, + thd->priv_host, + (thd->password ? + ER(ER_YES) : + ER(ER_NO)));/* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -4085,10 +4127,13 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_PRINT("error",("Access denied")); if (!no_errors) - my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), - thd->priv_user, - thd->priv_host, - db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */ + my_printf_error(ER_DBACCESS_DENIED_ERROR, + ER(ER_DBACCESS_DENIED_ERROR), MYF(0), + thd->priv_user, + thd->priv_host, + (db ? db : (thd->db ? + thd->db : + "unknown"))); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4122,7 +4167,8 @@ bool check_global_access(THD *thd, ulong want_access) if ((thd->master_access & want_access)) return 0; get_privilege_desc(command, sizeof(command), want_access); - my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); + my_printf_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, + ER(ER_SPECIFIC_ACCESS_DENIED_ERROR), MYF(0), command); return 1; #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4234,7 +4280,8 @@ static bool check_db_used(THD *thd,TABLE_LIST *tables) { if (!(tables->db=thd->db)) { - my_error(ER_NO_DB_ERROR, MYF(0)); /* purecov: tested */ + my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), + MYF(0)); /* purecov: tested */ return TRUE; /* purecov: tested */ } } @@ -4272,7 +4319,8 @@ check_sp_definer_access(THD *thd, sp_head *sp) strncmp(thd->priv_host, hst->str, hst->length) == 0) return FALSE; /* Both user and host must match */ - my_error(ER_SP_ACCESS_DENIED_ERROR, MYF(0), sp->m_qname.str); + my_printf_error(ER_SP_ACCESS_DENIED_ERROR, ER(ER_SP_ACCESS_DENIED_ERROR), + MYF(0), sp->m_qname.str); return TRUE; /* Not definer or root */ } @@ -4636,7 +4684,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (strlen(field_name) > NAME_LEN) { - my_error(ER_TOO_LONG_IDENT, MYF(0), field_name); /* purecov: inspected */ + my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), + field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (type_modifier & PRI_KEY_FLAG) @@ -4667,7 +4716,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC && type == FIELD_TYPE_TIMESTAMP)) { - my_error(ER_INVALID_DEFAULT, MYF(0), field_name); + my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), + field_name); DBUG_RETURN(1); } else if (default_value->type() == Item::NULL_ITEM) @@ -4676,20 +4726,23 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { - my_error(ER_INVALID_DEFAULT, MYF(0), field_name); + my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), + field_name); DBUG_RETURN(1); } } else if (type_modifier & AUTO_INCREMENT_FLAG) { - my_error(ER_INVALID_DEFAULT, MYF(0), field_name); + my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), + field_name); DBUG_RETURN(1); } } if (on_update_value && type != FIELD_TYPE_TIMESTAMP) { - my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name); + my_printf_error(ER_INVALID_ON_UPDATE, ER(ER_INVALID_ON_UPDATE), MYF(0), + field_name); DBUG_RETURN(1); } @@ -4815,8 +4868,9 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res=default_value->val_str(&str); if (res->length()) { - my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), - field_name); /* purecov: inspected */ + my_printf_error(ER_BLOB_CANT_HAVE_DEFAULT, + ER(ER_BLOB_CANT_HAVE_DEFAULT), MYF(0), + field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->def=0; @@ -4836,7 +4890,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, uint tmp_length=new_field->length; if (tmp_length > PRECISION_FOR_DOUBLE) { - my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); + my_printf_error(ER_WRONG_FIELD_SPEC, ER(ER_WRONG_FIELD_SPEC), MYF(0), + field_name); DBUG_RETURN(1); } else if (tmp_length > PRECISION_FOR_FLOAT) @@ -4922,7 +4977,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { if (interval->count > sizeof(longlong)*8) { - my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */ + my_printf_error(ER_TOO_BIG_SET, ER(ER_TOO_BIG_SET), MYF(0), + field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->pack_length=(interval->count+7)/8; @@ -4952,7 +5008,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, ¬_used2, ¬_used3); if (thd->cuted_fields) { - my_error(ER_INVALID_DEFAULT, MYF(0), field_name); + my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), + field_name); DBUG_RETURN(1); } } @@ -4978,7 +5035,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res->strip_sp(); if (!find_type(interval, res->ptr(), res->length(), 0)) { - my_error(ER_INVALID_DEFAULT, MYF(0), field_name); + my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), + field_name); DBUG_RETURN(1); } } @@ -4992,14 +5050,15 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING && type != FIELD_TYPE_GEOMETRY)) { - my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name, - MAX_FIELD_CHARLENGTH); /* purecov: inspected */ + my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH), MYF(0), + field_name, MAX_FIELD_CHARLENGTH);/* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } type_modifier&= AUTO_INCREMENT_FLAG; if ((~allowed_type_modifier) & type_modifier) { - my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); + my_printf_error(ER_WRONG_FIELD_SPEC, ER(ER_WRONG_FIELD_SPEC), MYF(0), + field_name); DBUG_RETURN(1); } if (!new_field->pack_length) @@ -5129,7 +5188,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (check_table_name(table->table.str,table->table.length) || table->db.str && check_db_name(table->db.str)) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); + my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), + table->table.str); DBUG_RETURN(0); } @@ -5137,7 +5197,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, { if (table->sel) { - my_error(ER_DERIVED_MUST_HAVE_ALIAS, MYF(0)); + my_message(ER_DERIVED_MUST_HAVE_ALIAS, + ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0)); DBUG_RETURN(0); } if (!(alias_str=thd->memdup(alias_str,table->table.length+1))) @@ -5191,7 +5252,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) && !strcmp(ptr->db, tables->db)) { - my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */ + my_printf_error(ER_NONUNIQ_TABLE, ER(ER_NONUNIQ_TABLE), MYF(0), + alias_str); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */ } } @@ -5735,7 +5797,8 @@ static bool append_file_to_dir(THD *thd, const char **filename_ptr, if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 || !test_if_hard_path(*filename_ptr)) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr); + my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), + *filename_ptr); return 1; } /* Fix is using unix filename format on dos */ @@ -5768,7 +5831,8 @@ bool check_simple_select() char command[80]; strmake(command, thd->lex->yylval->symbol.str, min(thd->lex->yylval->symbol.length, sizeof(command)-1)); - my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command); + my_printf_error(ER_CANT_USE_OPTION_HERE, ER(ER_CANT_USE_OPTION_HERE), + MYF(0), command); return 1; } return 0; @@ -5916,7 +5980,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) if (select_lex->item_list.elements != lex->value_list.elements) { - my_error(ER_WRONG_VALUE_COUNT, MYF(0)); + my_printf_error(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); DBUG_RETURN(TRUE); } /* @@ -5997,7 +6061,8 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) DBUG_RETURN(TRUE); if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where) { - my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, MYF(0)); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); DBUG_RETURN(TRUE); } for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local) @@ -6014,8 +6079,8 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) } if (!walk) { - my_error(ER_UNKNOWN_TABLE, MYF(0), target_tbl->real_name, - "MULTI DELETE"); + my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), + target_tbl->real_name, "MULTI DELETE"); DBUG_RETURN(TRUE); } walk->lock_type= target_tbl->lock_type; @@ -6069,7 +6134,7 @@ bool update_precheck(THD *thd, TABLE_LIST *tables) DBUG_ENTER("update_precheck"); if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements) { - my_error(ER_WRONG_VALUE_COUNT, MYF(0)); + my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); DBUG_RETURN(TRUE); } DBUG_RETURN(check_db_used(thd, tables) || @@ -6127,7 +6192,7 @@ bool insert_precheck(THD *thd, TABLE_LIST *tables, bool update) if (lex->select_lex.item_list.elements != lex->value_list.elements) { - my_error(ER_WRONG_VALUE_COUNT, MYF(0)); + my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); DBUG_RETURN(TRUE); } DBUG_RETURN(FALSE); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index aa5da98f56f..17f1b0eacfd 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1451,7 +1451,7 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) All other is not supported yet */ res= -1; - my_error(ER_UNSUPPORTED_PS, MYF(0)); + my_message(ER_UNSUPPORTED_PS, ER(ER_UNSUPPORTED_PS), MYF(0)); goto error; } if (res == 0) diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 3298eb68a91..25874e1335a 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -44,7 +44,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) if (thd->locked_tables || thd->active_transaction()) { - my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); DBUG_RETURN(1); } @@ -156,7 +157,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) unpack_filename(name, name); if (!access(name,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_alias); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + MYF(0), new_alias); DBUG_RETURN(ren_table); // This can't be skipped } sprintf(name,"%s/%s/%s%s",mysql_data_home, @@ -165,7 +167,8 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) unpack_filename(name, name); if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN) { - my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); + my_printf_error(ER_FILE_NOT_FOUND, ER(ER_FILE_NOT_FOUND), MYF(0), + name, my_errno); if (!skip_error) DBUG_RETURN(ren_table); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 16daba09954..aea65d13386 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -296,7 +296,7 @@ bool purge_error_message(THD* thd, int res) if (errmsg) { - my_error(errmsg, MYF(0)); + my_message(errmsg, ER(errmsg), MYF(0)); return TRUE; } send_ok(thd); @@ -867,7 +867,7 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) if (slave_errno) { if (net_report) - my_error(slave_errno, MYF(0)); + my_message(slave_errno, ER(slave_errno), MYF(0)); DBUG_RETURN(1); } else if (net_report) @@ -917,7 +917,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report ) if (slave_errno) { if (net_report) - my_error(slave_errno, MYF(0)); + my_message(slave_errno, ER(slave_errno), MYF(0)); return 1; } else if (net_report) @@ -998,8 +998,8 @@ int reset_slave(THD *thd, MASTER_INFO* mi) err: unlock_slave_threads(mi); - if (error) - my_error(sql_errno, MYF(0), errmsg); + if (error) + my_printf_error(sql_errno, ER(sql_errno), MYF(0), errmsg); DBUG_RETURN(error); } @@ -1063,7 +1063,7 @@ bool change_master(THD* thd, MASTER_INFO* mi) init_thread_mask(&thread_mask,mi,0 /*not inverse*/); if (thread_mask) // We refuse if any slave thread is running { - my_error(ER_SLAVE_MUST_STOP, MYF(0)); + my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); unlock_slave_threads(mi); DBUG_RETURN(TRUE); } @@ -1073,7 +1073,7 @@ bool change_master(THD* thd, MASTER_INFO* mi) // TODO: see if needs re-write if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) { - my_error(ER_MASTER_INFO, MYF(0)); + my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); unlock_slave_threads(mi); DBUG_RETURN(TRUE); } @@ -1192,7 +1192,8 @@ bool change_master(THD* thd, MASTER_INFO* mi) 0 /* not only reset, but also reinit */, &errmsg)) { - my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); + my_printf_error(ER_RELAY_LOG_FAIL, ER(ER_RELAY_LOG_FAIL), MYF(0), + errmsg); unlock_slave_threads(mi); DBUG_RETURN(TRUE); } @@ -1208,7 +1209,7 @@ bool change_master(THD* thd, MASTER_INFO* mi) 0 /*no data lock*/, &msg, 0)) { - my_error(ER_RELAY_LOG_INIT, MYF(0), msg); + my_printf_error(ER_RELAY_LOG_INIT, ER(ER_RELAY_LOG_INIT), MYF(0), msg); unlock_slave_threads(mi); DBUG_RETURN(TRUE); } @@ -1259,7 +1260,8 @@ int reset_master(THD* thd) { if (!mysql_bin_log.is_open()) { - my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG)); + my_message(ER_FLUSH_MASTER_BINLOG_CLOSED, + ER(ER_FLUSH_MASTER_BINLOG_CLOSED), MYF(ME_BELL+ME_WAITTANG)); return 1; } return mysql_bin_log.reset_logs(thd); @@ -1401,8 +1403,9 @@ err: if (errmsg) { - my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), - "SHOW BINLOG EVENTS", errmsg); + my_printf_error(ER_ERROR_WHEN_EXECUTING_COMMAND, + ER(ER_ERROR_WHEN_EXECUTING_COMMAND), MYF(0), + "SHOW BINLOG EVENTS", errmsg); DBUG_RETURN(TRUE); } @@ -1470,7 +1473,7 @@ bool show_binlogs(THD* thd) if (!mysql_bin_log.is_open()) { - my_error(ER_NO_BINARY_LOGGING, MYF(0)); + my_message(ER_NO_BINARY_LOGGING, ER(ER_NO_BINARY_LOGGING), MYF(0)); return 1; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index df7e943d1f6..eed16be059a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -377,7 +377,8 @@ JOIN::prepare(Item ***rref_pointer_array, } if (flag == 3) { - my_error(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,MYF(0)); + my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS, + ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0)); DBUG_RETURN(-1); } } @@ -404,7 +405,8 @@ JOIN::prepare(Item ***rref_pointer_array, { if (!test_if_subpart(procedure->group,group_list)) { /* purecov: inspected */ - my_error(ER_DIFF_GROUPS_PROC, MYF(0)); /* purecov: inspected */ + my_message(ER_DIFF_GROUPS_PROC, ER(ER_DIFF_GROUPS_PROC), + MYF(0)); /* purecov: inspected */ goto err; /* purecov: inspected */ } } @@ -417,7 +419,8 @@ JOIN::prepare(Item ***rref_pointer_array, #endif if (order && (procedure->flags & PROC_NO_SORT)) { /* purecov: inspected */ - my_error(ER_ORDER_WITH_PROC, MYF(0)); /* purecov: inspected */ + my_message(ER_ORDER_WITH_PROC, ER(ER_ORDER_WITH_PROC), + MYF(0)); /* purecov: inspected */ goto err; /* purecov: inspected */ } } @@ -1805,7 +1808,7 @@ Cursor::fetch(ulong num_rows) if (thd->killed) /* Aborted by user */ { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); + my_message(ER_SERVER_SHUTDOWN, ER(ER_SERVER_SHUTDOWN), MYF(0)); return -1; } @@ -2209,7 +2212,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, if (s->dependent & s->table->map) { join->tables=0; // Don't use join->table - my_error(ER_WRONG_OUTER_JOIN,MYF(0)); + my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0)); DBUG_RETURN(1); } s->key_dependent= s->dependent; @@ -5622,7 +5625,8 @@ bool error_if_full_join(JOIN *join) { if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) { - my_error(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,MYF(0)); + my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, + ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); return(1); } } @@ -10664,7 +10668,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, } if (copy_blobs(first_field)) { - my_error(ER_OUTOFMEMORY,MYF(0)); + my_message(ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0)); error=0; goto err; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 17e1a77645a..f8243e8568e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -866,8 +866,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) /* TODO: add environment variables show when it become possible */ if (thd->lex->only_view && !table_list->view) { - my_error(ER_WRONG_OBJECT, MYF(0), table_list->db, - table_list->real_name, "VIEW"); + my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), + table_list->db, table_list->real_name, "VIEW"); DBUG_RETURN(TRUE); } @@ -936,7 +936,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, if (check_db_name(dbname)) { - my_error(ER_WRONG_DB_NAME, MYF(0), dbname); + my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), dbname); DBUG_RETURN(TRUE); } @@ -948,8 +948,9 @@ bool mysqld_show_create_db(THD *thd, char *dbname, thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), - thd->priv_user, thd->host_or_ip, dbname); + my_printf_error(ER_DBACCESS_DENIED_ERROR, + ER(ER_DBACCESS_DENIED_ERROR), MYF(0), + thd->priv_user, thd->host_or_ip, dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->host_or_ip, dbname); DBUG_RETURN(TRUE); @@ -966,7 +967,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, } if (access(path,F_OK)) { - my_error(ER_BAD_DB_ERROR, MYF(0), dbname); + my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), dbname); DBUG_RETURN(TRUE); } if (found_libchar) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d84611ae496..77a5ab340b3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -78,8 +78,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, { if (thd->global_read_lock) { - my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0), - tables->real_name); + my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, + ER(ER_TABLE_NOT_LOCKED_FOR_WRITE), MYF(0), + tables->real_name); error= TRUE; goto err; } @@ -261,9 +262,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (wrong_tables.length()) { if (!foreign_key_error) - my_error(ER_BAD_TABLE_ERROR,MYF(0), wrong_tables.c_ptr()); + my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), + wrong_tables.c_ptr()); else - my_error(ER_ROW_IS_REFERENCED, MYF(0)); + my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); error= 1; } @@ -463,7 +465,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (check_column_name(sql_field->field_name)) { - my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name); + my_printf_error(ER_WRONG_COLUMN_NAME, ER(ER_WRONG_COLUMN_NAME), MYF(0), + sql_field->field_name); DBUG_RETURN(-1); } @@ -480,7 +483,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (field_no < select_field_pos || dup_no >= select_field_pos) { - my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); + my_printf_error(ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME), MYF(0), + sql_field->field_name); DBUG_RETURN(-1); } else @@ -619,24 +623,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (timestamps_with_niladic > 1) { - my_error(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,MYF(0)); + my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS, + ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0)); DBUG_RETURN(-1); } if (auto_increment > 1) { - my_error(ER_WRONG_AUTO_KEY,MYF(0)); + my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); DBUG_RETURN(-1); } if (auto_increment && (file->table_flags() & HA_NO_AUTO_INCREMENT)) { - my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,MYF(0)); + my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, + ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0)); DBUG_RETURN(-1); } if (blob_columns && (file->table_flags() & HA_NO_BLOBS)) { - my_error(ER_TABLE_CANT_HANDLE_BLOB,MYF(0)); + my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB), + MYF(0)); DBUG_RETURN(-1); } @@ -662,9 +669,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (fk_key->ref_columns.elements && fk_key->ref_columns.elements != fk_key->columns.elements) { - my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : - "foreign key without name", - ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); + my_printf_error(ER_WRONG_FK_DEF, ER(ER_WRONG_FK_DEF), MYF(0), + (fk_key->name ? + fk_key->name : + "foreign key without name"), + ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); DBUG_RETURN(-1); } continue; @@ -678,7 +687,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (key->name && strlen(key->name) > NAME_LEN) { - my_error(ER_TOO_LONG_IDENT, MYF(0), key->name); + my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), + key->name); DBUG_RETURN(-1); } key_iterator2.rewind (); @@ -718,7 +728,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (key->name && !tmp_table && !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); + my_printf_error(ER_WRONG_NAME_FOR_INDEX, ER(ER_WRONG_NAME_FOR_INDEX), + MYF(0), key->name); DBUG_RETURN(-1); } } @@ -786,7 +797,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->table_flags() & HA_CAN_FULLTEXT)) { - my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); + my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT), + MYF(0)); DBUG_RETURN(-1); } } @@ -927,7 +939,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (key->type == Key::SPATIAL) { - my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0)); + my_message(ER_SPATIAL_CANT_HAVE_NULL, + ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0)); DBUG_RETURN(-1); } } @@ -973,7 +986,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, (key_info->flags & HA_NOSAME))) && column->length != length))) { - my_error(ER_WRONG_SUB_KEY,MYF(0)); + my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0)); DBUG_RETURN(-1); } else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS)) @@ -1026,7 +1039,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (primary_key) { - my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); + my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY), + MYF(0)); DBUG_RETURN(-1); } key_name=primary_key_name; @@ -1037,7 +1051,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info_buffer,key_info); if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) { - my_error(ER_DUP_KEYNAME,MYF(0),key_name); + my_printf_error(ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), MYF(0), + key_name); DBUG_RETURN(-1); } key_info->name=(char*) key_name; @@ -1045,7 +1060,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (!key_info->name || check_column_name(key_info->name)) { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name); + my_printf_error(ER_WRONG_NAME_FOR_INDEX, ER(ER_WRONG_NAME_FOR_INDEX), + MYF(0), key_info->name); DBUG_RETURN(-1); } if (!(key_info->flags & HA_NULL_PART_KEY)) @@ -1062,12 +1078,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (!unique_key && !primary_key && (file->table_flags() & HA_REQUIRE_PRIMARY_KEY)) { - my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0)); + my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0)); DBUG_RETURN(-1); } if (auto_increment > 0) { - my_error(ER_WRONG_AUTO_KEY,MYF(0)); + my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0)); DBUG_RETURN(-1); } /* Sort keys in optimized order */ @@ -1123,7 +1139,8 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, /* Check for duplicate fields and check type of table to create */ if (!fields.elements) { - my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0)); + my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS), + MYF(0)); DBUG_RETURN(TRUE); } if ((new_db_type= ha_checktype(create_info->db_type)) != @@ -1153,7 +1170,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && (file->table_flags() & HA_NO_TEMP_TABLES)) { - my_error(ER_ILLEGAL_HA,MYF(0),table_name); + my_printf_error(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0), table_name); DBUG_RETURN(TRUE); } #endif @@ -1204,7 +1221,8 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(FALSE); } - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), MYF(0), + alias); DBUG_RETURN(TRUE); } if (wait_if_global_read_lock(thd, 0, 1)) @@ -1220,7 +1238,8 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, error= FALSE; } else - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_printf_error(ER_TABLE_EXISTS_ERROR, + ER(ER_TABLE_EXISTS_ERROR), MYF(0), table_name); goto end; } } @@ -1249,7 +1268,8 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, error= FALSE; } else - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_printf_error(ER_TABLE_EXISTS_ERROR, + ER(ER_TABLE_EXISTS_ERROR), MYF(0), table_name); goto end; } } @@ -1457,7 +1477,8 @@ mysql_rename_table(enum db_type base, } delete file; if (error) - my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); + my_printf_error(ER_ERROR_ON_RENAME, ER(ER_ERROR_ON_RENAME), + MYF(0), from, to, error); DBUG_RETURN(error != 0); } @@ -1999,7 +2020,8 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, if (!(key_cache= get_key_cache(key_cache_name))) { pthread_mutex_unlock(&LOCK_global_system_variables); - my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); + my_printf_error(ER_UNKNOWN_KEY_CACHE, ER(ER_UNKNOWN_KEY_CACHE), MYF(0), + key_cache_name->str); DBUG_RETURN(TRUE); } pthread_mutex_unlock(&LOCK_global_system_variables); @@ -2109,7 +2131,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, check_table_name(src_table,table_ident->table.length)) || table_ident->db.str && check_db_name((src_db= table_ident->db.str))) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); + my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), + src_table); DBUG_RETURN(TRUE); } @@ -2128,7 +2151,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, reg_ext, NullS); if (access(src_path, F_OK)) { - my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); + my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), + src_table); goto err; } } @@ -2211,7 +2235,8 @@ table_exists: res= FALSE; } else - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), MYF(0), + table_name); err: pthread_mutex_lock(&LOCK_open); @@ -2467,7 +2492,8 @@ int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list, } if (idx>= table->keys) { - my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop_key->name); + my_printf_error(ER_CANT_DROP_FIELD_OR_KEY, ER(ER_CANT_DROP_FIELD_OR_KEY), + MYF(0), drop_key->name); /*don't need to free((gptr) key_numbers);*/ DBUG_RETURN(-1); } @@ -2590,7 +2616,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (find_temporary_table(thd,new_db,new_name_buff)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + MYF(0), new_name_buff); DBUG_RETURN(TRUE); } } @@ -2600,7 +2627,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, F_OK)) { /* Table will be closed in do_command() */ - my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + MYF(0), new_alias); DBUG_RETURN(TRUE); } } @@ -2640,7 +2668,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, error=0; if (!access(new_name_buff,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + MYF(0), new_name); error= -1; } else @@ -2783,7 +2812,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (def->sql_type == FIELD_TYPE_BLOB) { - my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change); + my_printf_error(ER_BLOB_CANT_HAVE_DEFAULT, + ER(ER_BLOB_CANT_HAVE_DEFAULT), MYF(0), def->change); DBUG_RETURN(TRUE); } def->def=alter->def; // Use new default @@ -2797,7 +2827,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (def->change && ! def->field) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),def->change,table_name); + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + def->change, table_name); DBUG_RETURN(TRUE); } if (!def->after) @@ -2815,7 +2846,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } if (!find) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name); + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), + MYF(0), def->after, table_name); DBUG_RETURN(TRUE); } find_it.after(def); // Put element after this @@ -2823,13 +2855,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } if (alter_info->alter_list.elements) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),alter_info->alter_list.head()->name, - table_name); + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), + alter_info->alter_list.head()->name, table_name); DBUG_RETURN(TRUE); } if (!create_list.elements) { - my_error(ER_CANT_REMOVE_ALL_FIELDS,MYF(0)); + my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS), + MYF(0)); DBUG_RETURN(TRUE); } @@ -2918,7 +2951,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (key->name && !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); + my_printf_error(ER_WRONG_NAME_FOR_INDEX, ER(ER_WRONG_NAME_FOR_INDEX), + MYF(0), key->name); DBUG_RETURN(TRUE); } } @@ -2926,14 +2960,16 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (alter_info->drop_list.elements) { - my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0), - alter_info->drop_list.head()->name); + my_printf_error(ER_CANT_DROP_FIELD_OR_KEY, + ER(ER_CANT_DROP_FIELD_OR_KEY), MYF(0), + alter_info->drop_list.head()->name); goto err; } if (alter_info->alter_list.elements) { - my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0), - alter_info->alter_list.head()->name); + my_printf_error(ER_CANT_DROP_FIELD_OR_KEY, + ER(ER_CANT_DROP_FIELD_OR_KEY), MYF(0), + alter_info->alter_list.head()->name); goto err; } @@ -3121,7 +3157,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!access(new_name_buff,F_OK)) { error=1; - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + MYF(0), new_name_buff); VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(pthread_mutex_unlock(&LOCK_open)); goto err; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index b71bb4ba42a..13f127cc54b 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -74,7 +74,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) */ if (tables->view || table->tmp_table != NO_TMP_TABLE) { - my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); + my_printf_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, + ER(ER_TRG_ON_VIEW_OR_TEMP_TABLE), MYF(0), tables->alias); DBUG_RETURN(TRUE); } @@ -82,7 +83,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) { if (!create) { - my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); + my_message(ER_TRG_DOES_NOT_EXIST, ER(ER_TRG_DOES_NOT_EXIST), MYF(0)); DBUG_RETURN(TRUE); } @@ -142,7 +143,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) /* We don't allow creation of several triggers of the same type yet */ if (bodies[lex->trg_chistics.event][lex->trg_chistics.action_time]) { - my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); + my_message(ER_TRG_ALREADY_EXISTS, ER(ER_TRG_ALREADY_EXISTS), MYF(0)); return 1; } @@ -152,7 +153,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) if (my_strcasecmp(system_charset_info, lex->name_and_length.str, name->str) == 0) { - my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); + my_message(ER_TRG_ALREADY_EXISTS, ER(ER_TRG_ALREADY_EXISTS), MYF(0)); return 1; } } @@ -266,7 +267,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables) } } - my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); + my_message(ER_TRG_DOES_NOT_EXIST, ER(ER_TRG_DOES_NOT_EXIST), MYF(0)); return 1; } @@ -433,7 +434,8 @@ err_with_lex_cleanup: We don't care about this error message much because .TRG files will be merged into .FRM anyway. */ - my_error(ER_WRONG_OBJECT, MYF(0), table_name, triggers_file_ext, "TRIGGER"); + my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), + table_name, triggers_file_ext, "TRIGGER"); DBUG_RETURN(1); } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index d27b72c02a7..903b80e6949 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -369,7 +369,7 @@ int mysql_create_function(THD *thd,udf_func *udf) if (!initialized) { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); DBUG_RETURN(1); } @@ -380,19 +380,20 @@ int mysql_create_function(THD *thd,udf_func *udf) */ if (strchr(udf->dl, '/')) { - my_error(ER_UDF_NO_PATHS, MYF(0)); + my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0)); DBUG_RETURN(1); } if (udf->name.length > NAME_LEN) { - my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name); + my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), + udf->name); DBUG_RETURN(1); } rw_wrlock(&THR_LOCK_udf); if ((hash_search(&udf_hash,(byte*) udf->name.str, udf->name.length))) { - my_error(ER_UDF_EXISTS, MYF(0), udf->name); + my_printf_error(ER_UDF_EXISTS, ER(ER_UDF_EXISTS), MYF(0), udf->name); goto err; } if (!(dl = find_udf_dl(udf->dl))) @@ -401,7 +402,8 @@ int mysql_create_function(THD *thd,udf_func *udf) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", udf->dl,errno,dlerror())); - my_error(ER_CANT_OPEN_LIBRARY, MYF(0), udf->dl, errno, dlerror()); + my_printf_error(ER_CANT_OPEN_LIBRARY, ER(ER_CANT_OPEN_LIBRARY), MYF(0), + udf->dl, errno, dlerror()); goto err; } new_dl=1; @@ -411,7 +413,8 @@ int mysql_create_function(THD *thd,udf_func *udf) if (udf->func == NULL) { - my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), udf->name); + my_printf_error(ER_CANT_FIND_DL_ENTRY, ER(ER_CANT_FIND_DL_ENTRY), MYF(0), + udf->name); goto err; } udf->name.str=strdup_root(&mem,udf->name.str); @@ -445,7 +448,8 @@ int mysql_create_function(THD *thd,udf_func *udf) close_thread_tables(thd); if (error) { - my_error(ER_ERROR_ON_WRITE, MYF(0), "func@mysql", error); + my_printf_error(ER_ERROR_ON_WRITE, ER(ER_ERROR_ON_WRITE), MYF(0), + "func@mysql", error); del_udf(u_d); goto err; } @@ -468,14 +472,15 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) DBUG_ENTER("mysql_drop_function"); if (!initialized) { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); DBUG_RETURN(1); } rw_wrlock(&THR_LOCK_udf); if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name->str, (uint) udf_name->length))) { - my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), udf_name->str); + my_printf_error(ER_FUNCTION_NOT_DEFINED, ER(ER_FUNCTION_NOT_DEFINED), + MYF(0), udf_name->str); goto err; } del_udf(udf); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 6a2d11ba7f5..5969f1ce3fa 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -75,7 +75,7 @@ bool select_union::send_data(List &values) unit->offset_limit_cnt--; return 0; } - fill_record(table->field, values, 1); + fill_record(thd, table->field, values, 1); if (thd->net.report_error || write_record(thd, table,&info)) { if (thd->net.last_errno == ER_RECORD_FILE_FULL) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 8d64d30a9e0..ccdc64638bb 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -73,7 +73,8 @@ static bool check_fields(THD *thd, List &items) if (!(field= item->filed_for_view_update())) { /* item has name, because it comes from VIEW SELECT list */ - my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name); + my_printf_error(ER_NONUPDATEABLE_COLUMN, ER(ER_NONUPDATEABLE_COLUMN), + MYF(0), item->name); return TRUE; } /* @@ -164,7 +165,8 @@ bool mysql_update(THD *thd, } if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); + my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), + MYF(0), table_list->alias, "UPDATE"); DBUG_RETURN(TRUE); } if (table->timestamp_field) @@ -362,16 +364,9 @@ bool mysql_update(THD *thd, if (!(select && select->skip_record())) { store_record(table,record[1]); - if (fill_record(fields,values, 0) || thd->net.report_error) - { - /* Field::store methods can't send errors */ - if (!thd->net.report_error) - { - /* TODO: convert last warning to error */ - my_error(ER_UNKNOWN_ERROR, MYF(0)); - } + if (fill_record(thd, fields, values, 0)) break; /* purecov: inspected */ - } + found++; if (table->triggers) @@ -478,7 +473,7 @@ bool mysql_update(THD *thd, thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */ thd->abort_on_warning= 0; free_io_cache(table); - DBUG_RETURN(FALSE); + DBUG_RETURN(error >= 0 || thd->net.report_error); err: delete select; @@ -504,11 +499,10 @@ err: order - ORDER BY clause list RETURN VALUE - 0 - OK - 1 - error (message is sent to user) - -1 - error (message is not sent to user) + FALSE OK + TRUE error */ -int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, +bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, Item **conds, uint order_num, ORDER *order) { TABLE *table= table_list->table; @@ -532,16 +526,17 @@ int mysql_prepare_update(THD *thd, TABLE_LIST *table_list, setup_order(thd, select_lex->ref_pointer_array, table_list, all_fields, all_fields, order) || setup_ftfuncs(select_lex)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); /* Check that we are not using table that we are updating in a sub select */ if (unique_table(table_list, table_list->next_independent())) { - my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); - DBUG_RETURN(-1); + my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), MYF(0), + table_list->real_name); + DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, conds); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -655,7 +650,8 @@ bool mysql_multi_update_prepare(THD *thd) if ((readonly_tables & tl->table->map) && (tables_for_update & tl->table->map)) { - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE"); + my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), + MYF(0), tl->alias, "UPDATE"); DBUG_RETURN(TRUE); } } @@ -741,7 +737,7 @@ int multi_update::prepare(List ¬_used_values, if (!tables_to_update) { - my_error(ER_NO_TABLES_USED, MYF(0)); + my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0)); DBUG_RETURN(1); } @@ -1028,16 +1024,10 @@ bool multi_update::send_data(List ¬_used_values) { table->status|= STATUS_UPDATED; store_record(table,record[1]); - if (fill_record(*fields_for_table[offset], *values_for_table[offset], 0)) - { - /* Field::store methods can't send errors */ - if (!thd->net.report_error) - { - /* TODO: convert last warning to error */ - my_error(ER_UNKNOWN_ERROR, MYF(0)); - } + if (fill_record(thd, *fields_for_table[offset], + *values_for_table[offset], 0)) DBUG_RETURN(1); - } + found++; if (compare_record(table, thd->query_id)) { @@ -1075,7 +1065,7 @@ bool multi_update::send_data(List ¬_used_values) { int error; TABLE *tmp_table= tmp_tables[offset]; - fill_record(tmp_table->field+1, *values_for_table[offset], 1); + fill_record(thd, tmp_table->field+1, *values_for_table[offset], 1); found++; /* Store pointer to row */ memcpy((char*) tmp_table->field[0]->ptr, diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 7894287aee4..296d6c16590 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -71,9 +71,10 @@ bool mysql_create_view(THD *thd, if (lex->derived_tables || lex->variables_used || lex->param_list.elements) { - my_error((lex->derived_tables ? + int err= (lex->derived_tables ? ER_VIEW_SELECT_DERIVED : - ER_VIEW_SELECT_VARIABLE), MYF(0)); + ER_VIEW_SELECT_VARIABLE); + my_message(err, ER(err), MYF(0)); res= TRUE; goto err; } @@ -188,7 +189,8 @@ bool mysql_create_view(THD *thd, /* is this table temporary and is not view? */ if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view) { - my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias); + my_printf_error(ER_VIEW_SELECT_TMPTABLE, + ER(ER_VIEW_SELECT_TMPTABLE), MYF(0), tbl->alias); res= TRUE; goto err; } @@ -198,7 +200,8 @@ bool mysql_create_view(THD *thd, strcmp(tbl->view_db.str, view->db) == 0 && strcmp(tbl->view_name.str, view->real_name) == 0) { - my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str); + my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), + tbl->view_db.str, tbl->view_name.str); res= TRUE; goto err; } @@ -253,7 +256,8 @@ bool mysql_create_view(THD *thd, { if (strcmp(item->name, check->name) == 0) { - my_error(ER_DUP_FIELDNAME, MYF(0), item->name); + my_printf_error(ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME), + MYF(0), item->name); DBUG_RETURN(TRUE); } } @@ -426,7 +430,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { if (mode == VIEW_CREATE_NEW) { - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias); + my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + MYF(0), view->alias); DBUG_RETURN(-1); } @@ -436,8 +441,9 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (!parser->ok() || strncmp("VIEW", parser->type()->str, parser->type()->length)) { - my_error(ER_WRONG_OBJECT, MYF(0), (view->db ? view->db : thd->db), - view->real_name, "VIEW"); + my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), + (view->db ? view->db : thd->db), + view->real_name, "VIEW"); DBUG_RETURN(-1); } @@ -457,7 +463,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { if (mode == VIEW_ALTER) { - my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias); + my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), + view->db, view->alias); DBUG_RETURN(-1); } } @@ -500,7 +507,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (view->with_check != VIEW_CHECK_NONE && !view->updatable_view) { - my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->real_name); + my_printf_error(ER_VIEW_NONUPD_CHECK, ER(ER_VIEW_NONUPD_CHECK), MYF(0), + view->db, view->real_name); DBUG_RETURN(-1); } @@ -671,7 +679,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) if (check_table_access(thd, SELECT_ACL, view_tables, 1) && check_table_access(thd, SHOW_VIEW_ACL, table, 1)) { - my_error(ER_VIEW_NO_EXPLAIN, MYF(0)); + my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0)); goto err; } } @@ -851,9 +859,11 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) continue; } if (type) - my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->real_name, "VIEW"); + my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), + view->db, view->real_name, "VIEW"); else - my_error(ER_BAD_TABLE_ERROR, MYF(0), name); + my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), + name); goto err; } if (my_delete(path, MYF(MY_WME))) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bdeb5a7d98d..ccffefc4b8e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -813,7 +813,7 @@ query: if (!thd->bootstrap && (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) { - my_error(ER_EMPTY_QUERY, MYF(0)); + my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0)); YYABORT; } else @@ -1463,7 +1463,8 @@ sp_fdparam: if (spc->find_pvar(&$1, TRUE)) { - my_error(ER_SP_DUP_PARAM, MYF(0), $1.str); + my_printf_error(ER_SP_DUP_PARAM, ER(ER_SP_DUP_PARAM), MYF(0), + $1.str); YYABORT; } spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); @@ -1489,7 +1490,8 @@ sp_pdparam: if (spc->find_pvar(&$2, TRUE)) { - my_error(ER_SP_DUP_PARAM, MYF(0), $2.str); + my_printf_error(ER_SP_DUP_PARAM, ER(ER_SP_DUP_PARAM), MYF(0), + $2.str); YYABORT; } spc->push_pvar(&$2, (enum enum_field_types)$3, @@ -1523,12 +1525,14 @@ sp_decls: better error handling this way.) */ if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs)) { /* Variable or condition following cursor or handler */ - my_error(ER_SP_VARCOND_AFTER_CURSHNDLR, MYF(0)); + my_message(ER_SP_VARCOND_AFTER_CURSHNDLR, + ER(ER_SP_VARCOND_AFTER_CURSHNDLR), MYF(0)); YYABORT; } if ($2.curs && $1.hndlrs) { /* Cursor following handler */ - my_error(ER_SP_CURSOR_AFTER_HANDLER, MYF(0)); + my_message(ER_SP_CURSOR_AFTER_HANDLER, + ER(ER_SP_CURSOR_AFTER_HANDLER), MYF(0)); YYABORT; } $$.vars= $1.vars + $2.vars; @@ -1576,7 +1580,8 @@ sp_decl: if (spc->find_cond(&$2, TRUE)) { - my_error(ER_SP_DUP_COND, MYF(0), $2.str); + my_printf_error(ER_SP_DUP_COND, ER(ER_SP_DUP_COND), MYF(0), + $2.str); YYABORT; } YYTHD->lex->spcont->push_cond(&$2, $5); @@ -1633,7 +1638,8 @@ sp_decl: if (ctx->find_cursor(&$2, &offp, TRUE)) { - my_error(ER_SP_DUP_CURS, MYF(0), $2.str); + my_printf_error(ER_SP_DUP_CURS, ER(ER_SP_DUP_CURS), MYF(0), + $2.str); delete $5; YYABORT; } @@ -1660,12 +1666,14 @@ sp_cursor_stmt: if (lex->sql_command != SQLCOM_SELECT) { - my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0)); + my_message(ER_SP_BAD_CURSOR_QUERY, ER(ER_SP_BAD_CURSOR_QUERY), + MYF(0)); YYABORT; } if (lex->result) { - my_error(ER_SP_BAD_CURSOR_SELECT, MYF(0)); + my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT), + MYF(0)); YYABORT; } lex->sp_lex_in_use= TRUE; @@ -1735,7 +1743,8 @@ sp_hcond: $$= Lex->spcont->find_cond(&$1); if ($$ == NULL) { - my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + my_printf_error(ER_SP_COND_MISMATCH, ER(ER_SP_COND_MISMATCH), + MYF(0), $1.str); YYABORT; } } @@ -1764,7 +1773,8 @@ sp_decl_idents: if (spc->find_pvar(&$1, TRUE)) { - my_error(ER_SP_DUP_VAR, MYF(0), $1.str); + my_printf_error(ER_SP_DUP_VAR, ER(ER_SP_DUP_VAR), MYF(0), + $1.str); YYABORT; } spc->push_pvar(&$1, (enum_field_types)0, sp_param_in); @@ -1777,7 +1787,8 @@ sp_decl_idents: if (spc->find_pvar(&$3, TRUE)) { - my_error(ER_SP_DUP_VAR, MYF(0), $3.str); + my_printf_error(ER_SP_DUP_VAR, ER(ER_SP_DUP_VAR), MYF(0), + $3.str); YYABORT; } spc->push_pvar(&$3, (enum_field_types)0, sp_param_in); @@ -1810,7 +1821,7 @@ sp_proc_stmt: } if (lex->sql_command == SQLCOM_CHANGE_DB) { /* "USE db" doesn't work in a procedure */ - my_error(ER_SP_NO_USE, MYF(0)); + my_message(ER_SP_NO_USE, ER(ER_SP_NO_USE), MYF(0)); YYABORT; } /* Don't add an instruction for empty SET statements. @@ -1829,7 +1840,7 @@ sp_proc_stmt: */ if (sp->m_type != TYPE_ENUM_PROCEDURE) { - my_error(ER_SP_BADSTATEMENT, MYF(0)); + my_message(ER_SP_BADSTATEMENT, ER(ER_SP_BADSTATEMENT), MYF(0)); YYABORT; } else @@ -1859,7 +1870,7 @@ sp_proc_stmt: if (lex->sphead->m_type == TYPE_ENUM_PROCEDURE) { - my_error(ER_SP_BADRETURN, MYF(0)); + my_message(ER_SP_BADRETURN, ER(ER_SP_BADRETURN), MYF(0)); YYABORT; } else @@ -1868,7 +1879,7 @@ sp_proc_stmt: if ($2->type() == Item::SUBSELECT_ITEM) { /* QQ For now, just disallow subselects as values */ - my_error(ER_SP_BADSTATEMENT, MYF(0)); + my_message(ER_SP_BADSTATEMENT, ER(ER_SP_BADSTATEMENT), MYF(0)); YYABORT; } i= new sp_instr_freturn(lex->sphead->instructions(), @@ -1931,7 +1942,9 @@ sp_proc_stmt: if (! lab) { - my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str); + my_printf_error(ER_SP_LILABEL_MISMATCH, + ER(ER_SP_LILABEL_MISMATCH), MYF(0), + "LEAVE", $2.str); YYABORT; } else @@ -1961,7 +1974,9 @@ sp_proc_stmt: if (! lab || lab->type != SP_LAB_ITER) { - my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str); + my_printf_error(ER_SP_LILABEL_MISMATCH, + ER(ER_SP_LILABEL_MISMATCH), MYF(0), + "ITERATE", $2.str); YYABORT; } else @@ -1989,7 +2004,8 @@ sp_proc_stmt: if (lab) { - my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str); + my_printf_error(ER_SP_LABEL_REDEFINE, + ER(ER_SP_LABEL_REDEFINE), MYF(0), $2.str); YYABORT; } else @@ -2013,7 +2029,7 @@ sp_proc_stmt: if (sp->m_in_handler) { - my_error(ER_SP_GOTO_IN_HNDLR, MYF(0)); + my_message(ER_SP_GOTO_IN_HNDLR, ER(ER_SP_GOTO_IN_HNDLR), MYF(0)); YYABORT; } lab= ctx->find_label($2.str); @@ -2064,7 +2080,8 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); + my_printf_error(ER_SP_CURSOR_MISMATCH, + ER(ER_SP_CURSOR_MISMATCH), MYF(0), $2.str); YYABORT; } i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); @@ -2079,7 +2096,8 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); + my_printf_error(ER_SP_CURSOR_MISMATCH, + ER(ER_SP_CURSOR_MISMATCH), MYF(0), $2.str); YYABORT; } i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); @@ -2096,7 +2114,8 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); + my_printf_error(ER_SP_CURSOR_MISMATCH, + ER(ER_SP_CURSOR_MISMATCH), MYF(0), $2.str); YYABORT; } i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); @@ -2114,7 +2133,8 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$1))) { - my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); + my_printf_error(ER_SP_UNDECLARED_VAR, + ER(ER_SP_UNDECLARED_VAR), MYF(0), $1.str); YYABORT; } else @@ -2136,7 +2156,8 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$3))) { - my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str); + my_printf_error(ER_SP_UNDECLARED_VAR, + ER(ER_SP_UNDECLARED_VAR), MYF(0), $3.str); YYABORT; } else @@ -2260,7 +2281,8 @@ sp_labeled_control: if (lab) { - my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str); + my_printf_error(ER_SP_LABEL_REDEFINE, + ER(ER_SP_LABEL_REDEFINE), MYF(0), $1.str); YYABORT; } else @@ -2281,7 +2303,8 @@ sp_labeled_control: if (!lab || my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) { - my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); + my_printf_error(ER_SP_LABEL_MISMATCH, + ER(ER_SP_LABEL_MISMATCH), MYF(0), $5.str); YYABORT; } } @@ -2539,9 +2562,11 @@ default_charset: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - my_error(ER_CONFLICTING_DECLARATIONS, MYF(0), - "CHARACTER SET ", cinfo->default_table_charset->csname, - "CHARACTER SET ", $4->csname); + my_printf_error(ER_CONFLICTING_DECLARATIONS, + ER(ER_CONFLICTING_DECLARATIONS), MYF(0), + "CHARACTER SET ", + cinfo->default_table_charset->csname, + "CHARACTER SET ", $4->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2556,8 +2581,9 @@ default_collation: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), - $4->name, cinfo->default_table_charset->csname); + my_printf_error(ER_COLLATION_CHARSET_MISMATCH, + ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), + $4->name, cinfo->default_table_charset->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2569,7 +2595,8 @@ storage_engines: { $$ = ha_resolve_by_name($1.str,$1.length); if ($$ == DB_TYPE_UNKNOWN) { - my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str); + my_printf_error(ER_UNKNOWN_STORAGE_ENGINE, + ER(ER_UNKNOWN_STORAGE_ENGINE), MYF(0), $1.str); YYABORT; } }; @@ -2755,9 +2782,10 @@ type: Lex->uint_geom_type= (uint)$1; $$=FIELD_TYPE_GEOMETRY; #else - my_error(ER_FEATURE_DISABLED, MYF(0) - sym_group_geom.name, - sym_group_geom.needed_define); + my_printf_error(ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), MYF(0) + sym_group_geom.name, + sym_group_geom.needed_define); YYABORT; #endif } @@ -2924,8 +2952,9 @@ attribute: { if (Lex->charset && !my_charset_same(Lex->charset,$2)) { - my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), - $2->name,Lex->charset->csname); + my_printf_error(ER_COLLATION_CHARSET_MISMATCH, + ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), + $2->name,Lex->charset->csname); YYABORT; } else @@ -2950,7 +2979,8 @@ charset_name: { if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) { - my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); + my_printf_error(ER_UNKNOWN_CHARACTER_SET, + ER(ER_UNKNOWN_CHARACTER_SET), MYF(0), $1.str); YYABORT; } } @@ -2968,7 +2998,8 @@ old_or_new_charset_name: if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) && !($$=get_old_charset_by_name($1.str))) { - my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); + my_printf_error(ER_UNKNOWN_CHARACTER_SET, + ER(ER_UNKNOWN_CHARACTER_SET), MYF(0), $1.str); YYABORT; } } @@ -2984,7 +3015,8 @@ collation_name: { if (!($$=get_charset_by_name($1.str,MYF(0)))) { - my_error(ER_UNKNOWN_COLLATION, MYF(0), $1.str); + my_printf_error(ER_UNKNOWN_COLLATION, + ER(ER_UNKNOWN_COLLATION), MYF(0), $1.str); YYABORT; } }; @@ -3073,8 +3105,9 @@ key_type: #ifdef HAVE_SPATIAL $$= Key::SPATIAL; #else - my_error(ER_FEATURE_DISABLED, MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_printf_error(ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif }; @@ -3106,7 +3139,7 @@ opt_unique_or_fulltext: #ifdef HAVE_SPATIAL $$= Key::SPATIAL; #else - my_error(ER_FEATURE_DISABLED, MYF(0), + my_message(ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), MYF(0), sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif @@ -3332,7 +3365,8 @@ alter_list_item: if (check_table_name($3->table.str,$3->table.length) || $3->db.str && check_db_name($3->db.str)) { - my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); + my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), + MYF(0), $3->table.str); YYABORT; } lex->alter_info.flags|= ALTER_RENAME; @@ -3347,8 +3381,9 @@ alter_list_item: $5= $5 ? $5 : $4; if (!my_charset_same($4,$5)) { - my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), - $5->name, $4->csname); + my_printf_error(ER_COLLATION_CHARSET_MISMATCH, + ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), + $5->name, $4->csname); YYABORT; } LEX *lex= Lex; @@ -3470,7 +3505,8 @@ slave_until: !((lex->mi.log_file_name && lex->mi.pos) || (lex->mi.relay_log_name && lex->mi.relay_log_pos))) { - my_error(ER_BAD_SLAVE_UNTIL_COND, MYF(0)); + my_message(ER_BAD_SLAVE_UNTIL_COND, + ER(ER_BAD_SLAVE_UNTIL_COND), MYF(0)); YYABORT; } @@ -4183,9 +4219,10 @@ simple_expr: { if (!$1.symbol->create_func) { - my_error(ER_FEATURE_DISABLED, MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_printf_error(ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(void))($1.symbol->create_func))(); @@ -4194,9 +4231,10 @@ simple_expr: { if (!$1.symbol->create_func) { - my_error(ER_FEATURE_DISABLED, MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_printf_error(ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*))($1.symbol->create_func))($3); @@ -4205,9 +4243,10 @@ simple_expr: { if (!$1.symbol->create_func) { - my_error(ER_FEATURE_DISABLED, MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_printf_error(ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5); @@ -4216,9 +4255,10 @@ simple_expr: { if (!$1.symbol->create_func) { - my_error(ER_FEATURE_DISABLED, MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_printf_error(ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7); @@ -4321,8 +4361,9 @@ simple_expr: #ifdef HAVE_SPATIAL $$= $1; #else - my_error(ER_FEATURE_DISABLED, MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_printf_error(ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif } @@ -5378,7 +5419,8 @@ select_var_ident: if (!lex->spcont || !(t=lex->spcont->find_pvar(&$1))) { - my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); + my_printf_error(ER_SP_UNDECLARED_VAR, + ER(ER_SP_UNDECLARED_VAR), MYF(0), $1.str); YYABORT; } if (! lex->result) @@ -5733,8 +5775,9 @@ update: else if (lex->select_lex.get_table_list()->derived) { /* it is single table update and it is update of derived table */ - my_error(ER_NON_UPDATABLE_TABLE, MYF(0), - lex->select_lex.get_table_list()->alias, "UPDATE"); + my_printf_error(ER_NON_UPDATABLE_TABLE, + ER(ER_NON_UPDATABLE_TABLE), MYF(0), + lex->select_lex.get_table_list()->alias, "UPDATE"); YYABORT; } } @@ -6241,7 +6284,8 @@ kill: LEX *lex=Lex; if ($3->fix_fields(lex->thd, 0, &$3) || $3->check_cols(1)) { - my_error(ER_SET_CONSTANTS_ONLY, MYF(0)); + my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), + MYF(0)); YYABORT; } lex->sql_command=SQLCOM_KILL; @@ -6388,7 +6432,7 @@ param_marker: (uchar *) thd->query)); if (!($$= item) || lex->param_list.push_back(item)) { - my_error(ER_OUT_OF_RESOURCES, MYF(0)); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); YYABORT; } } @@ -6564,8 +6608,9 @@ simple_ident_q: FIXME. Far from perfect solution. See comment for "SET NEW.field_name:=..." for more info. */ - my_error(ER_BAD_FIELD_ERROR, MYF(0), $3.str, - new_row ? "NEW": "OLD"); + my_printf_error(ER_BAD_FIELD_ERROR, + ER(ER_BAD_FIELD_ERROR), MYF(0), + $3.str, new_row ? "NEW": "OLD"); YYABORT; } @@ -6652,8 +6697,9 @@ IDENT_sys: $1.length); if (wlen < $1.length) { - my_error(ER_INVALID_CHARACTER_STRING, MYF(0), cs->csname, - $1.str + wlen); + my_printf_error(ER_INVALID_CHARACTER_STRING, + ER(ER_INVALID_CHARACTER_STRING), MYF(0), + cs->csname, $1.str + wlen); YYABORT; } $$= $1; @@ -7032,7 +7078,8 @@ option_value: */ if (lex->query_tables) { - my_error(ER_SP_SUBSELECT_NYI, MYF(0)); + my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI), + MYF(0)); YYABORT; } sp_instr_set_user_var *i= @@ -7055,7 +7102,8 @@ option_value: sp_instr_set_trigger_field *i; if (lex->query_tables) { - my_error(ER_SP_SUBSELECT_NYI, MYF(0)); + my_message(ER_SP_SUBSELECT_NYI, ER(ER_SP_SUBSELECT_NYI), + MYF(0)); YYABORT; } if ($3) @@ -7084,7 +7132,8 @@ option_value: Error message also should be improved. */ - my_error(ER_BAD_FIELD_ERROR, MYF(0), $1.base_name, "NEW"); + my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), + MYF(0), $1.base_name, "NEW"); YYABORT; } lex->sphead->add_instr(i); @@ -7150,8 +7199,9 @@ option_value: $3= $3 ? $3 : $2; if (!my_charset_same($2,$3)) { - my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), - $3->name, $2->csname); + my_printf_error(ER_COLLATION_CHARSET_MISMATCH, + ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), + $3->name, $2->csname); YYABORT; } lex->var_list.push_back(new set_var_collation_client($3,$3,$3)); @@ -7241,7 +7291,8 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); + my_printf_error(ER_VARIABLE_IS_NOT_STRUCT, + ER(ER_VARIABLE_IS_NOT_STRUCT), MYF(0), $3.str); $$.var= tmp; $$.base_name= $1; } @@ -7252,7 +7303,8 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); + my_printf_error(ER_VARIABLE_IS_NOT_STRUCT, + ER(ER_VARIABLE_IS_NOT_STRUCT), MYF(0), $3.str); $$.var= tmp; $$.base_name.str= (char*) "default"; $$.base_name.length= 7; @@ -7533,7 +7585,8 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); YYABORT; } } @@ -7545,7 +7598,8 @@ opt_table: lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); YYABORT; } } @@ -7557,7 +7611,8 @@ opt_table: lex->grant= GLOBAL_ACLS & ~GRANT_ACL; else if (lex->columns.elements) { - my_error(ER_ILLEGAL_GRANT_FOR_TABLE, MYF(0)); + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); YYABORT; } } diff --git a/sql/table.cc b/sql/table.cc index e372de57177..97b5a420279 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -957,11 +957,12 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype) uint length=dirname_part(buff,name); buff[length-1]=0; db=buff+dirname_length(buff); - my_error(ER_NO_SUCH_TABLE,MYF(0),db,form->real_name); + my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), + db, form->real_name); } else - my_error(ER_FILE_NOT_FOUND,errortype, - fn_format(buff,name,form_dev,reg_ext,0),my_errno); + my_printf_error(ER_FILE_NOT_FOUND, ER(ER_FILE_NOT_FOUND), errortype, + fn_format(buff, name, form_dev, reg_ext, 0), my_errno); break; case 2: { @@ -969,14 +970,15 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype) datext= datext==NullS ? "" : datext; err_no= (my_errno == ENOENT) ? ER_FILE_NOT_FOUND : (my_errno == EAGAIN) ? ER_FILE_USED : ER_CANT_OPEN_FILE; - my_error(err_no,errortype, - fn_format(buff,form->real_name,form_dev,datext,2),my_errno); + my_printf_error(err_no, ER(err_no), errortype, + fn_format(buff, form->real_name, form_dev, datext, 2), + my_errno); break; } default: /* Better wrong error than none */ case 4: - my_error(ER_NOT_FORM_FILE,errortype, - fn_format(buff,name,form_dev,reg_ext,0)); + my_printf_error(ER_NOT_FORM_FILE, ER(ER_NOT_FORM_FILE), errortype, + fn_format(buff, name, form_dev, reg_ext, 0)); break; } DBUG_VOID_RETURN; @@ -1694,7 +1696,8 @@ err: if (thd->net.last_errno == ER_BAD_FIELD_ERROR) { thd->clear_error(); - my_error(ER_VIEW_INVALID, MYF(0), view_db.str, view_name.str); + my_printf_error(ER_VIEW_INVALID, ER(ER_VIEW_INVALID), MYF(0), + view_db.str, view_name.str); } thd->lex->select_lex.no_wrap_view_item= save_wrapper; thd->lex->current_select= current_select_save; @@ -1730,7 +1733,8 @@ int st_table_list::view_check_option(THD *thd, bool ignore_failure) } else { - my_error(ER_VIEW_CHECK_FAILED, MYF(0), view_db.str, view_name.str); + my_printf_error(ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED), MYF(0), + view_db.str, view_name.str); return(VIEW_CHECK_ERROR); } } diff --git a/sql/unireg.cc b/sql/unireg.cc index 2a6abdb1cfd..8988c847476 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -383,7 +383,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, if (create_fields.elements > MAX_FIELDS) { - my_error(ER_TOO_MANY_FIELDS,MYF(0)); + my_message(ER_TOO_MANY_FIELDS, ER(ER_TOO_MANY_FIELDS), MYF(0)); DBUG_RETURN(1); } @@ -448,7 +448,7 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, if (info_length+(ulong) create_fields.elements*FCOMP+288+ n_length+int_length+com_length > 65535L || int_count > 255) { - my_error(ER_TOO_MANY_FIELDS,MYF(0)); + my_message(ER_TOO_MANY_FIELDS, ER(ER_TOO_MANY_FIELDS), MYF(0)); DBUG_RETURN(1); } -- cgit v1.2.1 From 3ab56a2b4beab159b53bd4a5a9bb9b1cb7a42994 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 14:38:01 +0200 Subject: Ensure that new connections are in state SLEEP (for nicer show processlist) --- sql/sql_parse.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a14a3da8391..c680b4e420d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1028,6 +1028,7 @@ pthread_handler_decl(handle_one_connection,arg) thd->version= refresh_version; thd->proc_info= 0; + thd->command= COM_SLEEP; thd->set_time(); thd->init_for_queries(); -- cgit v1.2.1 From bb43e8317fc3d78fd5f3d22a0ca0acf090540cd5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 17:04:07 +0300 Subject: Fix for bug #5890 "Triggers fail for DELETE without WHERE". If we have DELETE with always true WHERE clause we should not use optimized delete_all_rows() method for tables with DELETE triggers, because in this case we will lose side-effect of deletion. mysql-test/r/trigger.result: Added test for bug #5890 "Triggers fail for DELETE without WHERE". mysql-test/t/trigger.test: Added test for bug #5890 "Triggers fail for DELETE without WHERE". sql/sql_delete.cc: mysql_delete(): We should not use optimized delete_all_rows() method for tables with DELETE triggers, because in this case we will lose side-effect of deletion. sql/sql_trigger.h: Added new Table_triggers_list::has_delete_triggers() method which allows to understand quickly if we have some DELETE triggers in our list. --- sql/sql_delete.cc | 9 +++++++-- sql/sql_trigger.h | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8bdf19195f3..1cd0d0177f6 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -62,9 +62,14 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if (thd->lex->duplicates == DUP_IGNORE) thd->lex->select_lex.no_error= 1; - /* Test if the user wants to delete all rows */ + /* + Test if the user wants to delete all rows and deletion doesn't have + any side-effects (because of triggers), so we can use optimized + handler::delete_all_rows() method. + */ if (!using_limit && const_cond && (!conds || conds->val_int()) && - !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE))) + !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && + !(table->triggers && table->triggers->has_delete_triggers())) { deleted= table->file->records; if (!(error=table->file->delete_all_rows())) diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 8ab2ab003f8..d0376f056d9 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -58,5 +58,11 @@ public: static bool check_n_load(THD *thd, const char *db, const char *table_name, TABLE *table); + bool has_delete_triggers() + { + return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] || + bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]); + } + friend class Item_trigger_field; }; -- cgit v1.2.1 From 2c6a3b97733a6e22fba947adb9052e677ef21838 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 16:41:53 +0100 Subject: typos in error messages fixed sql/share/french/errmsg.txt: typos fixed sql/share/greek/errmsg.txt: typos fixed sql/share/portuguese/errmsg.txt: typos fixed sql/share/romanian/errmsg.txt: typos fixed sql/share/serbian/errmsg.txt: typos fixed sql/share/spanish/errmsg.txt: typos fixed sql/share/swedish/errmsg.txt: typos fixed --- sql/share/french/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/portuguese/errmsg.txt | 2 +- sql/share/romanian/errmsg.txt | 2 +- sql/share/serbian/errmsg.txt | 2 +- sql/share/spanish/errmsg.txt | 6 +++--- sql/share/swedish/errmsg.txt | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 355e784b156..bb2bd29171a 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -209,7 +209,7 @@ character-set=latin1 "Erreur d'écriture réseau reçue du maître", "Impossible de trouver un index FULLTEXT correspondant à cette liste de colonnes", "Impossible d'exécuter la commande car vous avez des tables verrouillées ou une transaction active", -"Variable système '%-.64' inconnue", +"Variable système '%-.64s' inconnue", "La table '%-.64s' est marquée 'crashed' et devrait être réparée", "La table '%-.64s' est marquée 'crashed' et le dernier 'repair' a échoué", "Attention: certaines tables ne supportant pas les transactions ont été changées et elles ne pourront pas être restituées", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 06f31a79a73..87168431595 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -168,7 +168,7 @@ character-set=greek "You have an error in your SQL syntax", "Delayed insert thread couldn't get requested lock for table %-.64s", "Too many delayed threads in use", -"Aborted connection %ld to db: '%-.64s' user: '%-32s' (%-.64s)", +"Aborted connection %ld to db: '%-.64s' user: '%-.32s' (%-.64s)", "Got a packet bigger than 'max_allowed_packet' bytes", "Got a read error from the connection pipe", "Got an error from fcntl()", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index c79c346008e..65d80918072 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -211,7 +211,7 @@ character-set=latin1 "Erro de rede gravando no 'master'", "Não pode encontrar um índice para o texto todo que combine com a lista de colunas", "Não pode executar o comando dado porque você tem tabelas ativas travadas ou uma transação ativa", -"Variável de sistema '%-.64' desconhecida", +"Variável de sistema '%-.64s' desconhecida", "Tabela '%-.64s' está marcada como danificada e deve ser reparada", "Tabela '%-.64s' está marcada como danificada e a última reparação (automática?) falhou", "Aviso: Algumas tabelas não-transacionais alteradas não puderam ser reconstituídas (rolled back)", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 7cb0427dc3f..01c22f00119 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -173,7 +173,7 @@ character-set=latin2 "Aveti o eroare in sintaxa RSQL", "Thread-ul pentru inserarea aminata nu a putut obtine lacatul (lock) pentru tabela %-.64s", "Prea multe threaduri aminate care sint in uz", -"Conectie terminata %ld la baza de date: '%-.64s' utilizator: '%-32s' (%-.64s)", +"Conectie terminata %ld la baza de date: '%-.64s' utilizator: '%-.32s' (%-.64s)", "Un packet mai mare decit 'max_allowed_packet' a fost primit", "Eroare la citire din cauza lui 'connection pipe'", "Eroare obtinuta de la fcntl()", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 45b56c8269c..06270f621e4 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -202,7 +202,7 @@ character-set=cp1250 "Greška u slanju mrežnih paketa na glavni server u klasteru", "Ne mogu da pronaðem 'FULLTEXT' indeks koli odgovara listi kolona", "Ne mogu da izvršim datu komandu zbog toga što su tabele zakljuèane ili je transakcija u toku", -"Nepoznata sistemska promenljiva '%-.64'", +"Nepoznata sistemska promenljiva '%-.64s'", "Tabela '%-.64s' je markirana kao ošteæena i trebala bi biti popravljena", "Tabela '%-.64s' je markirana kao ošteæena, a zadnja (automatska?) popravka je bila neuspela", "Upozorenje: Neke izmenjene tabele ne podržavaju komandu 'ROLLBACK'", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index bd2439c44a6..c5b4fd34eca 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -238,9 +238,9 @@ character-set=latin1 "No puede adicionar clave extranjera constraint", "No puede adicionar una línea hijo: falla de clave extranjera constraint", "No puede deletar una línea padre: falla de clave extranjera constraint", -"Error de coneccion a master: %-128s", -"Error executando el query en master: %-128%", -"Error de %s: %-128%", +"Error de coneccion a master: %-.128s", +"Error executando el query en master: %-.128s", +"Error de %s: %-.128s", "Equivocado uso de %s y %s", "El comando SELECT usado tiene diferente número de columnas", "No puedo ejecutar el query porque usted tiene conflicto de traba de lectura", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index da75e4fcede..4dc42389d89 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -101,7 +101,7 @@ character-set=latin1 "Tabellen '%-.64s' har inget index som motsvarar det angivna i CREATE INDEX. Skapa om tabellen", "Fältseparatorerna är vad som förväntades. Kontrollera mot manualen", "Man kan inte använda fast radlängd med blobs. Använd 'fields terminated by'", -"Textfilen '%' måste finnas i databasbiblioteket eller vara läsbar för alla", +"Textfilen '%.64s' måste finnas i databasbiblioteket eller vara läsbar för alla", "Filen '%-.64s' existerar redan", "Rader: %ld Bortagna: %ld Dubletter: %ld Varningar: %ld", "Rader: %ld Dubletter: %ld", @@ -200,7 +200,7 @@ character-set=latin1 "Fick fel %d vid ROLLBACK", "Fick fel %d vid FLUSH_LOGS", "Fick fel %d vid CHECKPOINT", -"Avbröt länken för tråd %ld till db '%-.64s', användare '%-.32s', host '%-.64s' (%.-64s)", +"Avbröt länken för tråd %ld till db '%-.64s', användare '%-.32s', host '%-.64s' (%-.64s)", "Tabellhanteraren klarar inte en binär kopiering av tabellen", "Binärloggen stängdes medan FLUSH MASTER utfördes", "Failed rebuilding the index of dumped table '%-.64s'", -- cgit v1.2.1 From 55ae2e788088067fe539020c5162f4cfd96dfe43 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 17:44:17 +0200 Subject: After merge fixes client/mysqldump.c: Merge with 4.0 (and reordering of options) client/mysqltest.c: Added DB as a user variable myisam/mi_check.c: Trivial cleanup mysql-test/r/grant.result: Move test to be in same order as in 4.0 mysql-test/r/mix_innodb_myisam_binlog.result: Updated results mysql-test/r/ps_1general.result: Updated tests to work after privilege fixes mysql-test/r/timezone3.result: Updated results to 4.1 mysql-test/t/ps_1general.test: Updated tests to work after privilege fixes sql-common/my_time.c: Applied sub-second patch from 4.0 sql/sql_acl.cc: More debugging --- sql/sql_acl.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9067d01a06d..98af43e17a7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -970,6 +970,7 @@ ulong acl_get(const char *host, const char *ip, db_access=0; host_access= ~0; char key[ACL_KEY_LENGTH],*tmp_db,*end; acl_entry *entry; + DBUG_ENTER("acl_get"); VOID(pthread_mutex_lock(&acl_cache->lock)); end=strmov((tmp_db=strmov(strmov(key, ip ? ip : "")+1,user)+1),db); @@ -983,7 +984,8 @@ ulong acl_get(const char *host, const char *ip, { db_access=entry->access; VOID(pthread_mutex_unlock(&acl_cache->lock)); - return db_access; + DBUG_PRINT("exit", ("access: 0x%lx", db_access)); + DBUG_RETURN(db_access); } /* @@ -1035,7 +1037,8 @@ exit: acl_cache->add(entry); } VOID(pthread_mutex_unlock(&acl_cache->lock)); - return (db_access & host_access); + DBUG_PRINT("exit", ("access: 0x%lx", db_access & host_access)); + DBUG_RETURN(db_access & host_access); } /* -- cgit v1.2.1 From 7dad39859f26bac7b042c0b58089102be5c7269e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 19:01:49 +0200 Subject: Fix to allow usage of 4.0 tables with 4.1 --- sql/field.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index f70a23e889a..bbd21247b8e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5943,6 +5943,7 @@ Field *make_field(char *ptr, uint32 field_length, if (!f_is_packed(pack_flag)) { if (field_type == FIELD_TYPE_STRING || + field_type == FIELD_TYPE_DECIMAL || // 3.23 or 4.0 string field_type == FIELD_TYPE_VAR_STRING) return new Field_string(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, -- cgit v1.2.1 From c77c58bb2d3fa05c3cb7a7d7d10c74a67441ca85 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 19:04:35 +0200 Subject: Changed some unneccessary calls to current_thd() into table->in_use --- sql/ha_heap.cc | 33 ++++++++++++++++++++------------- sql/ha_isam.cc | 27 +++++++++++++++------------ sql/ha_isammrg.cc | 9 +++++---- sql/ha_myisam.cc | 38 +++++++++++++++++++++++--------------- sql/ha_myisammrg.cc | 34 +++++++++++++++++++++------------- 5 files changed, 84 insertions(+), 57 deletions(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 3bb8383e488..1c8967c1a34 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -86,7 +86,7 @@ void ha_heap::set_keys_for_scanning(void) int ha_heap::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) @@ -96,7 +96,7 @@ int ha_heap::write_row(byte * buf) int ha_heap::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return heap_update(file,old_data,new_data); @@ -104,7 +104,7 @@ int ha_heap::update_row(const byte * old_data, byte * new_data) int ha_heap::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); return heap_delete(file,buf); } @@ -112,7 +112,8 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error = heap_rkey(file,buf,active_index, key, key_len, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; return error; @@ -121,7 +122,8 @@ int ha_heap::index_read(byte * buf, const byte * key, uint key_len, int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error= heap_rkey(file, buf, active_index, key, key_len, HA_READ_PREFIX_LAST); table->status= error ? STATUS_NOT_FOUND : 0; @@ -131,7 +133,8 @@ int ha_heap::index_read_last(byte *buf, const byte *key, uint key_len) int ha_heap::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error = heap_rkey(file, buf, index, key, key_len, find_flag); table->status = error ? STATUS_NOT_FOUND : 0; return error; @@ -140,7 +143,8 @@ int ha_heap::index_read_idx(byte * buf, uint index, const byte * key, int ha_heap::index_next(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=heap_rnext(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -149,7 +153,8 @@ int ha_heap::index_next(byte * buf) int ha_heap::index_prev(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_prev_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_prev_count, + &LOCK_status); int error=heap_rprev(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -158,7 +163,7 @@ int ha_heap::index_prev(byte * buf) int ha_heap::index_first(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=heap_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -168,7 +173,8 @@ int ha_heap::index_first(byte * buf) int ha_heap::index_last(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_last_count, + &LOCK_status); int error=heap_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -181,7 +187,7 @@ int ha_heap::rnd_init(bool scan) int ha_heap::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=heap_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; @@ -192,7 +198,8 @@ int ha_heap::rnd_pos(byte * buf, byte *pos) { int error; HEAP_PTR position; - statistic_increment(current_thd->status_var.ha_read_rnd_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); memcpy_fixed((char*) &position,pos,sizeof(HEAP_PTR)); error=heap_rrnd(file, buf, position); table->status=error ? STATUS_NOT_FOUND: 0; @@ -456,7 +463,7 @@ int ha_heap::create(const char *name, TABLE *table_arg, } } mem_per_row+= MY_ALIGN(table_arg->reclength + 1, sizeof(char*)); - max_rows = (ha_rows) (current_thd->variables.max_heap_table_size / + max_rows = (ha_rows) (table->in_use->variables.max_heap_table_size / mem_per_row); HP_CREATE_INFO hp_create_info; hp_create_info.auto_key= auto_key; diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index d703df7d2e3..7b4e88c8601 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -69,7 +69,7 @@ uint ha_isam::min_record_length(uint options) const int ha_isam::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count, &LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) @@ -79,7 +79,7 @@ int ha_isam::write_row(byte * buf) int ha_isam::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count, &LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return !nisam_update(file,old_data,new_data) ? 0 : my_errno ? my_errno : -1; @@ -87,14 +87,15 @@ int ha_isam::update_row(const byte * old_data, byte * new_data) int ha_isam::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count, &LOCK_status); return !nisam_delete(file,buf) ? 0 : my_errno ? my_errno : -1; } int ha_isam::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=nisam_rkey(file, buf, active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return !error ? 0 : my_errno ? my_errno : -1; @@ -103,7 +104,8 @@ int ha_isam::index_read(byte * buf, const byte * key, int ha_isam::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=nisam_rkey(file, buf, index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return !error ? 0 : my_errno ? my_errno : -1; @@ -111,7 +113,8 @@ int ha_isam::index_read_idx(byte * buf, uint index, const byte * key, int ha_isam::index_read_last(byte * buf, const byte * key, uint key_len) { - statistic_increment(current_thd->status_var.ha_read_key_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=nisam_rkey(file, buf, active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; @@ -120,7 +123,7 @@ int ha_isam::index_read_last(byte * buf, const byte * key, uint key_len) int ha_isam::index_next(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_next_count, + statistic_increment(table->in_use->status_var.ha_read_next_count, &LOCK_status); int error=nisam_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -129,7 +132,7 @@ int ha_isam::index_next(byte * buf) int ha_isam::index_prev(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_prev_count, + statistic_increment(table->in_use->status_var.ha_read_prev_count, &LOCK_status); int error=nisam_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -138,7 +141,7 @@ int ha_isam::index_prev(byte * buf) int ha_isam::index_first(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=nisam_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -147,7 +150,7 @@ int ha_isam::index_first(byte * buf) int ha_isam::index_last(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_last_count, + statistic_increment(table->in_use->status_var.ha_read_last_count, &LOCK_status); int error=nisam_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -161,7 +164,7 @@ int ha_isam::rnd_init(bool scan) int ha_isam::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=nisam_rrnd(file, buf, NI_POS_ERROR); table->status=error ? STATUS_NOT_FOUND: 0; @@ -170,7 +173,7 @@ int ha_isam::rnd_next(byte *buf) int ha_isam::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_count, &LOCK_status); int error=nisam_rrnd(file, buf, (ulong) ha_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; diff --git a/sql/ha_isammrg.cc b/sql/ha_isammrg.cc index 5a070087724..f9ed3af8f61 100644 --- a/sql/ha_isammrg.cc +++ b/sql/ha_isammrg.cc @@ -77,7 +77,7 @@ int ha_isammrg::write_row(byte * buf) int ha_isammrg::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count, &LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return !mrg_update(file,old_data,new_data) ? 0 : my_errno ? my_errno : -1; @@ -85,7 +85,7 @@ int ha_isammrg::update_row(const byte * old_data, byte * new_data) int ha_isammrg::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count, &LOCK_status); return !mrg_delete(file,buf) ? 0 : my_errno ? my_errno : -1; } @@ -128,7 +128,7 @@ int ha_isammrg::rnd_init(bool scan) int ha_isammrg::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=mrg_rrnd(file, buf, ~(mrg_off_t) 0); table->status=error ? STATUS_NOT_FOUND: 0; @@ -137,7 +137,8 @@ int ha_isammrg::rnd_next(byte *buf) int ha_isammrg::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count, &LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); int error=mrg_rrnd(file, buf, (ulong) ha_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; return !error ? 0 : my_errno ? my_errno : -1; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 7482c6d5fa8..58f10f67341 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -249,7 +249,7 @@ int ha_myisam::close(void) int ha_myisam::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); /* If we have a timestamp column, update it to the current time */ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) @@ -602,7 +602,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) local_testflag|= T_STATISTICS; param.testflag|= T_STATISTICS; // We get this for free statistics_done=1; - if (current_thd->variables.myisam_repair_threads>1) + if (thd->variables.myisam_repair_threads>1) { char buf[40]; /* TODO: respect myisam_repair_threads variable */ @@ -1084,7 +1084,7 @@ bool ha_myisam::is_crashed() const int ha_myisam::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return mi_update(file,old_data,new_data); @@ -1092,7 +1092,7 @@ int ha_myisam::update_row(const byte * old_data, byte * new_data) int ha_myisam::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); return mi_delete(file,buf); } @@ -1100,7 +1100,8 @@ int ha_myisam::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1109,7 +1110,8 @@ int ha_myisam::index_read(byte * buf, const byte * key, int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1118,7 +1120,8 @@ int ha_myisam::index_read_idx(byte * buf, uint index, const byte * key, int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1127,7 +1130,8 @@ int ha_myisam::index_read_last(byte * buf, const byte * key, uint key_len) int ha_myisam::index_next(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=mi_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1136,7 +1140,8 @@ int ha_myisam::index_next(byte * buf) int ha_myisam::index_prev(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_prev_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_prev_count, + &LOCK_status); int error=mi_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1145,7 +1150,7 @@ int ha_myisam::index_prev(byte * buf) int ha_myisam::index_first(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=mi_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -1155,7 +1160,8 @@ int ha_myisam::index_first(byte * buf) int ha_myisam::index_last(byte * buf) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_last_count, + &LOCK_status); int error=mi_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1166,7 +1172,8 @@ int ha_myisam::index_next_same(byte * buf, uint length __attribute__((unused))) { DBUG_ASSERT(inited==INDEX); - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=mi_rnext_same(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1182,7 +1189,7 @@ int ha_myisam::rnd_init(bool scan) int ha_myisam::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=mi_scan(file, buf); table->status=error ? STATUS_NOT_FOUND: 0; @@ -1196,7 +1203,8 @@ int ha_myisam::restart_rnd_next(byte *buf, byte *pos) int ha_myisam::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); int error=mi_rrnd(file, buf, ha_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -1606,7 +1614,7 @@ int ha_myisam::ft_read(byte * buf) if (!ft_handler) return -1; - thread_safe_increment(current_thd->status_var.ha_read_next_count, + thread_safe_increment(table->in_use->status_var.ha_read_next_count, &LOCK_status); // why ? error=ft_handler->please->read_next(ft_handler,(char*) buf); diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 903dd9dec2f..8cff61859b1 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -81,7 +81,7 @@ int ha_myisammrg::close(void) int ha_myisammrg::write_row(byte * buf) { - statistic_increment(current_thd->status_var.ha_write_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_write_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) table->timestamp_field->set_time(); if (table->next_number_field && buf == table->record[0]) @@ -91,7 +91,7 @@ int ha_myisammrg::write_row(byte * buf) int ha_myisammrg::update_row(const byte * old_data, byte * new_data) { - statistic_increment(current_thd->status_var.ha_update_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status); if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) table->timestamp_field->set_time(); return myrg_update(file,old_data,new_data); @@ -99,14 +99,15 @@ int ha_myisammrg::update_row(const byte * old_data, byte * new_data) int ha_myisammrg::delete_row(const byte * buf) { - statistic_increment(current_thd->status_var.ha_delete_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status); return myrg_delete(file,buf); } int ha_myisammrg::index_read(byte * buf, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=myrg_rkey(file,buf,active_index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -115,7 +116,8 @@ int ha_myisammrg::index_read(byte * buf, const byte * key, int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key, uint key_len, enum ha_rkey_function find_flag) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=myrg_rkey(file,buf,index, key, key_len, find_flag); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -123,7 +125,8 @@ int ha_myisammrg::index_read_idx(byte * buf, uint index, const byte * key, int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len) { - statistic_increment(current_thd->status_var.ha_read_key_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_key_count, + &LOCK_status); int error=myrg_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST); table->status=error ? STATUS_NOT_FOUND: 0; @@ -132,7 +135,8 @@ int ha_myisammrg::index_read_last(byte * buf, const byte * key, uint key_len) int ha_myisammrg::index_next(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=myrg_rnext(file,buf,active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -140,7 +144,8 @@ int ha_myisammrg::index_next(byte * buf) int ha_myisammrg::index_prev(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_prev_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_prev_count, + &LOCK_status); int error=myrg_rprev(file,buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -148,7 +153,7 @@ int ha_myisammrg::index_prev(byte * buf) int ha_myisammrg::index_first(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_first_count, + statistic_increment(table->in_use->status_var.ha_read_first_count, &LOCK_status); int error=myrg_rfirst(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; @@ -157,7 +162,8 @@ int ha_myisammrg::index_first(byte * buf) int ha_myisammrg::index_last(byte * buf) { - statistic_increment(current_thd->status_var.ha_read_last_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_last_count, + &LOCK_status); int error=myrg_rlast(file, buf, active_index); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -167,7 +173,8 @@ int ha_myisammrg::index_next_same(byte * buf, const byte *key __attribute__((unused)), uint length __attribute__((unused))) { - statistic_increment(current_thd->status_var.ha_read_next_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_next_count, + &LOCK_status); int error=myrg_rnext_same(file,buf); table->status=error ? STATUS_NOT_FOUND: 0; return error; @@ -180,7 +187,7 @@ int ha_myisammrg::rnd_init(bool scan) int ha_myisammrg::rnd_next(byte *buf) { - statistic_increment(current_thd->status_var.ha_read_rnd_next_count, + statistic_increment(table->in_use->status_var.ha_read_rnd_next_count, &LOCK_status); int error=myrg_rrnd(file, buf, HA_OFFSET_ERROR); table->status=error ? STATUS_NOT_FOUND: 0; @@ -189,7 +196,8 @@ int ha_myisammrg::rnd_next(byte *buf) int ha_myisammrg::rnd_pos(byte * buf, byte *pos) { - statistic_increment(current_thd->status_var.ha_read_rnd_count,&LOCK_status); + statistic_increment(table->in_use->status_var.ha_read_rnd_count, + &LOCK_status); int error=myrg_rrnd(file, buf, ha_get_ptr(pos,ref_length)); table->status=error ? STATUS_NOT_FOUND: 0; return error; -- cgit v1.2.1 From c77cb0a3210106772e59e78059461a4eb4d69e54 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 20:47:41 +0200 Subject: Fixed a function call. --- sql/item_strfunc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 3f659964a6c..5a23eec5a1b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2593,7 +2593,7 @@ String *Item_func_quote::val_str(String *str) uint arg_length, new_length; if (!arg) // Null argument { - str->copy("NULL", 4); // Return the string 'NULL' + str->copy("NULL", 4, collation.collation); // Return the string 'NULL' null_value= 0; return str; } -- cgit v1.2.1 From 7c6738fb3c6b5675d53e3c398b301213ebc892a7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 21:24:16 +0200 Subject: Portability fix for gcc 2.95.3 After merge fixes mysql-test/r/mix_innodb_myisam_binlog.result: After merge fixes mysys/default.c: After merge fixes sql/mysql_priv.h: Portability fix for gcc 2.95.3 sql/sql_base.cc: Portability fix for gcc 2.95.3 --- sql/mysql_priv.h | 6 +++--- sql/sql_base.cc | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7d1ffe97e08..62e4f849c67 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -649,8 +649,8 @@ bool drop_locked_tables(THD *thd,const char *db, const char *table_name); void abort_locked_tables(THD *thd,const char *db, const char *table_name); void execute_init_command(THD *thd, sys_var_str *init_command_var, rw_lock_t *var_mutex); -extern const Field *not_found_field; -extern const Field *view_ref_found; +extern Field *not_found_field; +extern Field *view_ref_found; enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND, IGNORE_ERRORS, REPORT_EXCEPT_NON_UNIQUE, @@ -776,7 +776,7 @@ TABLE *unlink_open_table(THD *thd,TABLE *list,TABLE *find); SQL_SELECT *make_select(TABLE *head, table_map const_tables, table_map read_tables, COND *conds, int *error, bool allow_null_cond= false); -extern const Item **not_found_item; +extern Item **not_found_item; Item ** find_item_in_list(Item *item, List &items, uint *counter, find_item_error_report_type report_error, bool *unaliased); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index eeb34f6b600..e690673c934 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2045,8 +2045,8 @@ bool rm_temporary_table(enum db_type base, char *path) ******************************************************************************/ /* Special Field pointers for find_field_in_tables returning */ -const Field *not_found_field= (Field*) 0x1; -const Field *view_ref_found= (Field*) 0x2; +Field *not_found_field= (Field*) 0x1; +Field *view_ref_found= (Field*) 0x2; #define WRONG_GRANT (Field*) -1 @@ -2447,7 +2447,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, */ /* Special Item pointer to serve as a return value from find_item_in_list(). */ -const Item **not_found_item= (const Item**) 0x1; +Item **not_found_item= (Item**) 0x1; Item ** -- cgit v1.2.1 From 02840d1ba3ff75b5ada58807f69e0bff73b9599c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Nov 2004 15:56:25 -0800 Subject: Needed for WL# 2094, MySQL Federated Storage Handler sql_string.h: simple string method to drop last character of a string (also decrements str_length) sql/sql_string.h: simple string method to drop last character of a string (also decrements str_length) BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/sql_string.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'sql') diff --git a/sql/sql_string.h b/sql/sql_string.h index cb5b1fb25fd..2101db40f92 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -141,6 +141,34 @@ public: bool set(longlong num, CHARSET_INFO *cs); bool set(ulonglong num, CHARSET_INFO *cs); bool set(double num,uint decimals, CHARSET_INFO *cs); + + /* + PMG 2004.11.12 + This is a method that works the same as perl's "chop". It simply + drops the last character of a string. This is useful in the case + of the federated storage handler where I'm building a unknown + number, list of values and fields to be used in a sql insert + statement to be run on the remote server, and have a comma after each. + When the list is complete, I "chop" off the trailing comma + + ex. + String stringobj; + stringobj.append("VALUES ('foo', 'fi', 'fo',"); + stringobj.chop(); + stringobj.append(")"); + + In this case, the value of string was: + + VALUES ('foo', 'fi', 'fo', + VALUES ('foo', 'fi', 'fo' + VALUES ('foo', 'fi', 'fo') + + */ + inline void chop() + { + Ptr[str_length--]= '\0'; + } + inline void free() { if (alloced) -- cgit v1.2.1 From 7281d2e3ae7665f442dc07124b365b5fae190a24 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 13 Nov 2004 13:56:39 +0300 Subject: WL#1629: SHOW with WHERE(partially) & WL#173: Create Data Dictionary Tables for SHOW Commands --- sql/ha_innodb.cc | 98 +++ sql/ha_innodb.h | 1 + sql/handler.h | 4 + sql/mysql_priv.h | 33 +- sql/opt_sum.cc | 2 +- sql/sql_acl.cc | 218 +++++- sql/sql_base.cc | 16 +- sql/sql_lex.cc | 1 + sql/sql_lex.h | 4 +- sql/sql_parse.cc | 216 +++--- sql/sql_select.cc | 29 +- sql/sql_show.cc | 2178 ++++++++++++++++++++++++++++++++++++++++------------- sql/sql_view.cc | 5 +- sql/sql_yacc.yy | 142 +++- sql/table.cc | 1 + sql/table.h | 54 ++ 16 files changed, 2320 insertions(+), 682 deletions(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 370458c6e01..7f92f9fd899 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4674,6 +4674,104 @@ ha_innobase::get_foreign_key_create_info(void) return(str); } + +int +ha_innobase::get_foreign_key_list(THD *thd, List *f_key_list) +{ + dict_foreign_t* foreign; + + DBUG_ENTER("get_foreign_key_list"); + row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; + ut_a(prebuilt != NULL); + update_thd(current_thd); + prebuilt->trx->op_info = (char*)"getting list of foreign keys"; + trx_search_latch_release_if_reserved(prebuilt->trx); + mutex_enter(&(dict_sys->mutex)); + foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list); + + while (foreign != NULL) + { + uint i; + FOREIGN_KEY_INFO f_key_info; + LEX_STRING *name= 0; + const char *tmp_buff; + + tmp_buff= foreign->id; + i= 0; + while (tmp_buff[i] != '/') + i++; + tmp_buff+= i + 1; + f_key_info.forein_id= make_lex_string(thd, f_key_info.forein_id, + tmp_buff, strlen(tmp_buff), 1); + tmp_buff= foreign->referenced_table_name; + i= 0; + while (tmp_buff[i] != '/') + i++; + f_key_info.referenced_db= make_lex_string(thd, f_key_info.referenced_db, + tmp_buff, i, 1); + tmp_buff+= i + 1; + f_key_info.referenced_table= make_lex_string(thd, + f_key_info.referenced_table, + tmp_buff, strlen(tmp_buff), 1); + + for (i= 0;;) + { + tmp_buff= foreign->foreign_col_names[i]; + name= make_lex_string(thd, name, tmp_buff, strlen(tmp_buff), 1); + f_key_info.foreign_fields.push_back(name); + tmp_buff= foreign->referenced_col_names[i]; + name= make_lex_string(thd, name, tmp_buff, strlen(tmp_buff), 1); + f_key_info.referenced_fields.push_back(name); + if (++i >= foreign->n_fields) + break; + } + + ulong length= 0; + if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE) + { + length=17; + tmp_buff= "ON DELETE CASCADE"; + } + else if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL) + { + length=18; + tmp_buff= "ON DELETE SET NULL"; + } + else if (foreign->type == DICT_FOREIGN_ON_DELETE_NO_ACTION) + { + length=19; + tmp_buff= "ON DELETE NO ACTION"; + } + else if (foreign->type == DICT_FOREIGN_ON_UPDATE_CASCADE) + { + length=17; + tmp_buff= "ON UPDATE CASCADE"; + } + else if (foreign->type == DICT_FOREIGN_ON_UPDATE_SET_NULL) + { + length=18; + tmp_buff= "ON UPDATE SET NULL"; + } + else if (foreign->type == DICT_FOREIGN_ON_UPDATE_NO_ACTION) + { + length=19; + tmp_buff= "ON UPDATE NO ACTION"; + } + f_key_info.constraint_method= make_lex_string(thd, + f_key_info.constraint_method, + tmp_buff, length, 1); + + FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *) + thd->memdup((gptr) &f_key_info, + sizeof(FOREIGN_KEY_INFO))); + f_key_list->push_back(pf_key_info); + foreign = UT_LIST_GET_NEXT(foreign_list, foreign); + } + mutex_exit(&(dict_sys->mutex)); + prebuilt->trx->op_info = (char*)""; + DBUG_RETURN(0); +} + /*********************************************************************** Checks if a table is referenced by a foreign key. The MySQL manual states that a REPLACE is either equivalent to an INSERT, or DELETE(s) + INSERT. Only a diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 7e337afed0e..f9588bee055 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -162,6 +162,7 @@ class ha_innobase: public handler int check(THD* thd, HA_CHECK_OPT* check_opt); char* update_table_comment(const char* comment); char* get_foreign_key_create_info(); + int get_foreign_key_list(THD *thd, List *f_key_list); uint referenced_by_foreign_key(); void free_foreign_key_create_info(char* str); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, diff --git a/sql/handler.h b/sql/handler.h index 858a7861dba..31c6e2f902b 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -223,6 +223,8 @@ typedef struct st_ha_create_information struct st_table; typedef struct st_table TABLE; +struct st_foreign_key_info; +typedef struct st_foreign_key_info FOREIGN_KEY_INFO; typedef struct st_ha_check_opt { @@ -465,6 +467,8 @@ public: virtual char* get_foreign_key_create_info() { return(NULL);} /* gets foreign key create string from InnoDB */ /* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */ + virtual int get_foreign_key_list(THD *thd, List *f_key_list) + { return 0; } virtual uint referenced_by_foreign_key() { return 0;} virtual void init_table_handle_for_HANDLER() { return; } /* prepare InnoDB for HANDLER */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 62e4f849c67..5af64604cbd 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -247,6 +247,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; key checks in some cases */ #define OPTION_RELAXED_UNIQUE_CHECKS (1L << 27) #define SELECT_NO_UNLOCK (1L << 28) +#define OPTION_SCHEMA_TABLE (1L << 29) /* The rest of the file is included in the server only */ #ifndef MYSQL_CLIENT @@ -405,7 +406,8 @@ typedef Comp_creator* (*chooser_compare_func_creator)(bool invert); void free_items(Item *item); void cleanup_items(Item *item); class THD; -void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0); +void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0, + TABLE *stopper= 0); bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables); bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table); @@ -692,14 +694,7 @@ void free_des_key_file(); int mysql_do(THD *thd, List &values); /* sql_show.cc */ -int mysqld_show_dbs(THD *thd,const char *wild); int mysqld_show_open_tables(THD *thd,const char *wild); -int mysqld_show_tables(THD *thd, const char *db, const char *wild, - bool verbose); -int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild); -int mysqld_show_fields(THD *thd,TABLE_LIST *table, const char *wild, - bool verbose); -int mysqld_show_keys(THD *thd, TABLE_LIST *table); int mysqld_show_logs(THD *thd); void append_identifier(THD *thd, String *packet, const char *name, uint length); @@ -718,14 +713,32 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables, struct system_status_var *status_var); int mysql_find_files(THD *thd,List *files, const char *db, const char *path, const char *wild, bool dir); -int mysqld_show_charsets(THD *thd,const char *wild); -int mysqld_show_collations(THD *thd,const char *wild); int mysqld_show_storage_engines(THD *thd); int mysqld_show_privileges(THD *thd); int mysqld_show_column_types(THD *thd); int mysqld_help (THD *thd, const char *text); void calc_sum_of_all_status(STATUS_VAR *to); + + +/* information schema */ +extern LEX_STRING information_schema_name; +LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, + const char* str, uint length, + bool allocate_lex_string= 0); +ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name); +ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx); +int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, + enum enum_schema_tables schema_table_idx); +int make_schema_select(THD *thd, SELECT_LEX *sel, + enum enum_schema_tables schema_table_idx); +int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list); +int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond); +int get_schema_tables_result(JOIN *join); + /* sql_prepare.cc */ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, LEX_STRING *name=NULL); diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 30033bc39eb..f9a51a8348f 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -131,7 +131,7 @@ int opt_sum_query(TABLE_LIST *tables, List &all_fields,COND *conds) for (table= tables; table; table= table->next_local) { if (outer_tables || (table->table->file->table_flags() & - HA_NOT_EXACT_COUNT)) + HA_NOT_EXACT_COUNT) || table->schema_table) { const_result= 0; // Can't optimize left join break; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 59456c0eb2c..e796f275509 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2851,7 +2851,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, for (table= tables; table && number--; table= table->next_global) { GRANT_TABLE *grant_table; - if (!(~table->grant.privilege & want_access) || table->derived) + if (!(~table->grant.privilege & want_access) || + table->derived || table->schema_table) { /* It is subquery in the FROM clause. VIEW set table->derived after @@ -3928,6 +3929,221 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) DBUG_RETURN (*str != '\0'); } + +void update_schema_privilege(TABLE *table, char *buff, const char* db, + const char* t_name, const char* column, + uint col_length, const char *priv, + uint priv_length, const char* is_grantable) +{ + int i= 2; + CHARSET_INFO *cs= system_charset_info; + restore_record(table, default_values); + table->field[0]->store(buff, strlen(buff), cs); + if (db) + table->field[i++]->store(db, strlen(db), cs); + if (t_name) + table->field[i++]->store(t_name, strlen(t_name), cs); + if (column) + table->field[i++]->store(column, col_length, cs); + table->field[i++]->store(priv, priv_length, cs); + table->field[i]->store(is_grantable, strlen(is_grantable), cs); + table->file->write_row(table->record[0]); +} + + +int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint counter; + ACL_USER *acl_user; + ulong want_access; + + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_user_privileges"); + for (counter=0 ; counter < acl_users.elements ; counter++) + { + const char *user,*host, *is_grantable="YES"; + acl_user=dynamic_element(&acl_users,counter,ACL_USER*); + if (!(user=acl_user->user)) + user= ""; + if (!(host=acl_user->host.hostname)) + host= ""; + want_access= acl_user->access; + if (!(want_access & GRANT_ACL)) + is_grantable= "NO"; + + strxmov(buff,"'",user,"'@'",host,"'",NullS); + if (!(want_access & ~GRANT_ACL)) + update_schema_privilege(table, buff, 0, 0, 0, 0, "USAGE", 5, is_grantable); + else + { + uint priv_id; + ulong j,test_access= want_access & ~GRANT_ACL; + for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1) + { + if (test_access & j) + update_schema_privilege(table, buff, 0, 0, 0, 0, + command_array[priv_id], + command_lengths[priv_id], is_grantable); + } + } + } +#endif + DBUG_RETURN(0); +} + + +int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint counter; + ACL_DB *acl_db; + ulong want_access; + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_schema_privileges"); + + for (counter=0 ; counter < acl_dbs.elements ; counter++) + { + const char *user, *host, *is_grantable="YES"; + + acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); + if (!(user=acl_db->user)) + user= ""; + if (!(host=acl_db->host.hostname)) + host= ""; + + want_access=acl_db->access; + if (want_access) + { + if (!(want_access & GRANT_ACL)) + { + is_grantable= "NO"; + } + strxmov(buff,"'",user,"'@'",host,"'",NullS); + if (!(want_access & ~GRANT_ACL)) + update_schema_privilege(table, buff, acl_db->db, 0, 0, + 0, "USAGE", 5, is_grantable); + else + { + int cnt; + ulong j,test_access= want_access & ~GRANT_ACL; + for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) + if (test_access & j) + update_schema_privilege(table, buff, acl_db->db, 0, 0, 0, + command_array[cnt], command_lengths[cnt], + is_grantable); + } + } + } +#endif + DBUG_RETURN(0); +} + + +int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint index; + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_table_privileges"); + + for (index=0 ; index < column_priv_hash.records ; index++) + { + const char *user, *is_grantable= "YES"; + GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, + index); + if (!(user=grant_table->user)) + user= ""; + ulong table_access= grant_table->privs; + if (table_access != 0) + { + ulong test_access= table_access & ~GRANT_ACL; + if (!(table_access & GRANT_ACL)) + is_grantable= "NO"; + + strxmov(buff,"'",user,"'@'",grant_table->orig_host,"'",NullS); + if (!test_access) + update_schema_privilege(table, buff, grant_table->db, grant_table->tname, + 0, 0, "USAGE", 5, is_grantable); + else + { + ulong j; + int cnt; + for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1) + { + if (test_access & j) + update_schema_privilege(table, buff, grant_table->db, + grant_table->tname, 0, 0, command_array[cnt], + command_lengths[cnt], is_grantable); + } + } + } + } +#endif + DBUG_RETURN(0); +} + + +int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) +{ +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint index; + char buff[100]; + TABLE *table= tables->table; + DBUG_ENTER("fill_schema_table_privileges"); + + for (index=0 ; index < column_priv_hash.records ; index++) + { + const char *user, *is_grantable= "YES"; + GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, + index); + if (!(user=grant_table->user)) + user= ""; + ulong table_access= grant_table->cols; + if (table_access != 0) + { + ulong test_access= grant_table->cols & ~GRANT_ACL; + if (!(table_access & GRANT_ACL)) + is_grantable= "NO"; + + strxmov(buff,"'",user,"'@'",grant_table->orig_host,"'",NullS); + if (!test_access) + continue; + else + { + ulong j; + int cnt; + for (cnt= 0, j= SELECT_ACL; j <= TABLE_ACLS; cnt++, j<<= 1) + { + if (test_access & j) + { + for (uint col_index=0 ; + col_index < grant_table->hash_columns.records ; + col_index++) + { + GRANT_COLUMN *grant_column = (GRANT_COLUMN*) + hash_element(&grant_table->hash_columns,col_index); + if ((grant_column->rights & j) && (table_access & j)) + update_schema_privilege(table, buff, grant_table->db, + grant_table->tname, + grant_column->column, + grant_column->key_length, + command_array[cnt], + command_lengths[cnt], is_grantable); + } + } + } + } + } + } +#endif + DBUG_RETURN(0); +} + + #ifndef NO_EMBEDDED_ACCESS_CHECKS /* fill effective privileges for table diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e690673c934..9dc66f46afa 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -370,7 +370,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, Put all normal tables used by thread in free list. */ -void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) +void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived, + TABLE *stopper) { bool found_old_table; DBUG_ENTER("close_thread_tables"); @@ -408,7 +409,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived) DBUG_PRINT("info", ("thd->open_tables: %p", thd->open_tables)); found_old_table= 0; - while (thd->open_tables) + while (thd->open_tables != stopper) found_old_table|=close_thread_table(thd, &thd->open_tables); thd->some_tables_deleted=0; @@ -1656,6 +1657,12 @@ int open_tables(THD *thd, TABLE_LIST *start, uint *counter) */ if (tables->derived) continue; + if (tables->schema_table) + { + if (!mysql_schema_table(thd, thd->lex, tables)) + continue; + DBUG_RETURN(-1); + } (*counter)++; if (!tables->table && !(tables->table= open_table(thd, tables, &new_frm_mem, &refresh))) @@ -2904,7 +2911,7 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, &view_iter)) goto err; } - else + else if (!tables->schema_table) { table_iter.set(tables); if (check_grant_all_columns(thd, SELECT_ACL, &table->grant, @@ -2984,7 +2991,8 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, db= tables->db; tab= tables->real_name; } - if (!(fld->have_privileges= (get_column_grant(thd, + if (!tables->schema_table && + !(fld->have_privileges= (get_column_grant(thd, &table->grant, db, tab, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 86219abc632..68203d8ba20 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1057,6 +1057,7 @@ void st_select_lex::init_query() first_cond_optimization= 1; parsing_place= NO_MATTER; no_wrap_view_item= 0; + link_next= 0; } void st_select_lex::init_select() diff --git a/sql/sql_lex.h b/sql/sql_lex.h index fd1c1dee0b7..18c13efc528 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -56,7 +56,7 @@ enum enum_sql_command { SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, - SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, + SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_GRANT, @@ -692,7 +692,7 @@ typedef struct st_lex LEX_MASTER_INFO mi; // used by CHANGE MASTER USER_RESOURCES mqh; ulong thread_id,type; - enum_sql_command sql_command; + 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 */ enum my_lex_states next_state; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 726c4faa7bc..91f8defb2a7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1868,6 +1868,109 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } +int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, + enum enum_schema_tables schema_table_idx) +{ + DBUG_ENTER("prepare_schema_table"); + SELECT_LEX *sel= 0; + switch(schema_table_idx) { + case SCH_SCHEMATA: +#if defined(DONT_ALLOW_SHOW_COMMANDS) + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + DBUG_RETURN(1); +#else + if ((specialflag & SPECIAL_SKIP_SHOW_DB) && + check_global_access(thd, SHOW_DB_ACL)) + DBUG_RETURN(1); + break; +#endif + case SCH_TABLE_NAMES: + case SCH_TABLES: + case SCH_VIEWS: +#ifdef DONT_ALLOW_SHOW_COMMANDS + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + DBUG_RETURN(1); +#else + { + char *db= lex->select_lex.db ? lex->select_lex.db : thd->db; + if (!db) + { + send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ + DBUG_RETURN(1); /* purecov: inspected */ + } + remove_escape(db); // Fix escaped '_' + if (check_db_name(db)) + { + net_printf(thd,ER_WRONG_DB_NAME, db); + DBUG_RETURN(1); + } + if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) + DBUG_RETURN(1); /* purecov: inspected */ + if (!thd->col_access && check_grant_db(thd,db)) + { + net_printf(thd, ER_DBACCESS_DENIED_ERROR, + thd->priv_user, + thd->priv_host, + db); + DBUG_RETURN(1); + } + lex->select_lex.db= db; + break; + } +#endif + case SCH_COLUMNS: + case SCH_STATISTICS: +#ifdef DONT_ALLOW_SHOW_COMMANDS + send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + DBUG_RETURN(1); +#else + if (table_ident) + { + TABLE_LIST **query_tables_last= lex->query_tables_last; + sel= new SELECT_LEX(); + sel->init_query(); + if(!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, + (List *) 0, (List *) 0)) + DBUG_RETURN(1); + lex->query_tables_last= query_tables_last; + TABLE_LIST *table_list= (TABLE_LIST*) sel->table_list.first; + char *db= table_list->db; + remove_escape(db); // Fix escaped '_' + remove_escape(table_list->real_name); + if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, + &table_list->grant.privilege, 0, 0)) + DBUG_RETURN(1); /* purecov: inspected */ + if (grant_option && check_grant(thd, SELECT_ACL, table_list, 2, + UINT_MAX, 0)) + DBUG_RETURN(1); + break; + } +#endif + case SCH_PROCEDURES: + case SCH_CHARSETS: + case SCH_COLLATIONS: + case SCH_COLLATION_CHARACTER_SET_APPLICABILITY: + case SCH_USER_PRIVILEGES: + case SCH_SCHEMA_PRIVILEGES: + case SCH_TABLE_PRIVILEGES: + case SCH_COLUMN_PRIVILEGES: + case SCH_TABLE_CONSTRAINTS: + case SCH_KEY_COLUMN_USAGE: + default: + break; + } + + SELECT_LEX *select_lex= lex->current_select; + if (make_schema_select(thd, select_lex, schema_table_idx)) + { + DBUG_RETURN(1); + } + TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first; + table_list->schema_select_lex= sel; + DBUG_RETURN(0); +} + + /* Read query from packet and store in thd->query Used in COM_QUERY and COM_PREPARE @@ -3004,17 +3107,6 @@ unsent_create_error: else res = mysql_drop_index(thd, first_table, &lex->alter_info); break; - case SQLCOM_SHOW_DATABASES: -#if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - if ((specialflag & SPECIAL_SKIP_SHOW_DB) && - check_global_access(thd, SHOW_DB_ACL)) - goto error; - res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS)); - break; -#endif case SQLCOM_SHOW_PROCESSLIST: if (!thd->priv_user[0] && check_global_access(thd,PROCESS_ACL)) break; @@ -3061,96 +3153,10 @@ unsent_create_error: res= mysqld_show_logs(thd); break; } -#endif - case SQLCOM_SHOW_TABLES: - /* FALL THROUGH */ -#ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - { - char *db=select_lex->db ? select_lex->db : thd->db; - if (!db) - { - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ - goto error; /* purecov: inspected */ - } - remove_escape(db); // Fix escaped '_' - if (check_db_name(db)) - { - net_printf(thd,ER_WRONG_DB_NAME, db); - goto error; - } - if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) - goto error; /* purecov: inspected */ - if (!thd->col_access && check_grant_db(thd,db)) - { - net_printf(thd, ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - db); - goto error; - } - /* grant is checked in mysqld_show_tables */ - if (lex->describe) - res= mysqld_extend_show_tables(thd,db, - (lex->wild ? lex->wild->ptr() : NullS)); - else - res= mysqld_show_tables(thd, db, - (lex->wild ? lex->wild->ptr() : NullS), - lex->verbose); - break; - } #endif case SQLCOM_SHOW_OPEN_TABLES: res= mysqld_show_open_tables(thd,(lex->wild ? lex->wild->ptr() : NullS)); break; - case SQLCOM_SHOW_CHARSETS: - res= mysqld_show_charsets(thd,(lex->wild ? lex->wild->ptr() : NullS)); - break; - case SQLCOM_SHOW_COLLATIONS: - res= mysqld_show_collations(thd,(lex->wild ? lex->wild->ptr() : NullS)); - break; - case SQLCOM_SHOW_FIELDS: - DBUG_ASSERT(first_table == all_tables && first_table != 0); -#ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - { - char *db= first_table->db; - remove_escape(db); // Fix escaped '_' - remove_escape(first_table->real_name); - if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, - &first_table->grant.privilege, 0, 0)) - goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd, SELECT_ACL, first_table, 2, UINT_MAX, 0)) - goto error; - res= mysqld_show_fields(thd, first_table, - (lex->wild ? lex->wild->ptr() : NullS), - lex->verbose); - break; - } -#endif - case SQLCOM_SHOW_KEYS: - DBUG_ASSERT(first_table == all_tables && first_table != 0); -#ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ - goto error; -#else - { - char *db= first_table->db; - remove_escape(db); // Fix escaped '_' - remove_escape(first_table->real_name); - if (check_access(thd,SELECT_ACL | EXTRA_ACL,db, - &first_table->grant.privilege, 0, 0)) - goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd, SELECT_ACL, all_tables, 2, UINT_MAX, 0)) - goto error; - res= mysqld_show_keys(thd, first_table); - break; - } -#endif case SQLCOM_CHANGE_DB: mysql_change_db(thd,select_lex->db); break; @@ -4234,7 +4240,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, TABLE_LIST *org_tables=tables; for (; tables; tables= tables->next_global) { - if (tables->derived || + if (tables->derived || tables->schema_table || (tables->table && (int)tables->table->tmp_table) || my_tz_check_n_skip_implicit_tables(&tables, thd->lex->time_zone_tables_used)) @@ -4490,6 +4496,8 @@ mysql_init_select(LEX *lex) SELECT_LEX *select_lex= lex->current_select; select_lex->init_select(); select_lex->select_limit= HA_POS_ERROR; + lex->orig_sql_command= SQLCOM_END; + lex->wild= 0; if (select_lex == &lex->select_lex) { DBUG_ASSERT(lex->result == 0); @@ -5286,6 +5294,18 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX); ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES); ptr->derived= table->sel; + if (!my_strcasecmp(system_charset_info, ptr->db, + information_schema_name.str)) + { + ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->real_name); + if (!schema_table) + { + net_printf(thd, ER_UNKNOWN_TABLE, ptr->real_name, + information_schema_name.str); + DBUG_RETURN(0); + } + ptr->schema_table= schema_table; + } ptr->select_lex= lex->current_select; ptr->cacheable_table= 1; if (use_index_arg) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d07e274b0b7..3c7f1032f51 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1221,6 +1221,12 @@ JOIN::exec() List *curr_fields_list= &fields_list; TABLE *curr_tmp_table= 0; + if ((curr_join->select_lex->options & OPTION_SCHEMA_TABLE) && + get_schema_tables_result(curr_join)) + { + DBUG_VOID_RETURN; + } + /* Create a tmp table if distinct or if the sort is too complicated */ if (need_tmp) { @@ -2129,6 +2135,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, s->dependent= tables->dep_tables; s->key_dependent= 0; + if (tables->schema_table) + table->file->records= 2; s->on_expr_ref= &tables->on_expr; if (*s->on_expr_ref) @@ -7724,7 +7732,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, blob_count,group_null_items; bool using_unique_constraint=0; bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); - char *tmpname,path[FN_REFLEN]; + char *tmpname,path[FN_REFLEN], filename[FN_REFLEN]; byte *pos,*group_buff; uchar *null_flags; Field **reg_field, **from_field, **blob_field; @@ -7746,14 +7754,15 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, temp_pool_slot = bitmap_set_next(&temp_pool); if (temp_pool_slot != MY_BIT_NONE) // we got a slot - sprintf(path, "%s%s_%lx_%i", mysql_tmpdir, tmp_file_prefix, - current_pid, temp_pool_slot); + sprintf(filename, "%s_%lx_%i", tmp_file_prefix, + current_pid, temp_pool_slot); else // if we run out of slots or we are not using tempool - sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid, + sprintf(filename,"%s%lx_%lx_%x",tmp_file_prefix,current_pid, thd->thread_id, thd->tmp_table++); if (lower_case_table_names) my_casedn_str(files_charset_info, path); + sprintf(path, "%s%s", mysql_tmpdir, filename); if (group) { @@ -12879,8 +12888,16 @@ void st_table_list::print(THD *thd, String *str) { append_identifier(thd, str, db, db_length); str->append('.'); - append_identifier(thd, str, real_name, real_name_length); - cmp_name= real_name; + if (schema_table) + { + append_identifier(thd, str, alias, strlen(alias)); + cmp_name= alias; + } + else + { + append_identifier(thd, str, real_name, real_name_length); + cmp_name= real_name; + } } if (my_strcasecmp(table_alias_charset, cmp_name, alias)) { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7043379bf8f..2d27faa0e9c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -21,6 +21,7 @@ #include "sql_select.h" // For select_describe #include "sql_acl.h" #include "repl_failsafe.h" +#include "sp_head.h" #include #ifdef HAVE_BERKELEY_DB @@ -43,55 +44,6 @@ static int view_store_create_info(THD *thd, TABLE_LIST *table, String *packet); -/* - Report list of databases - A database is a directory in the mysql_data_home directory -*/ - -int -mysqld_show_dbs(THD *thd,const char *wild) -{ - Item_string *field=new Item_string("",0,thd->charset()); - List field_list; - char *end; - List files; - char *file_name; - Protocol *protocol= thd->protocol; - DBUG_ENTER("mysqld_show_dbs"); - - field->name=(char*) thd->alloc(20+ (wild ? (uint) strlen(wild)+4: 0)); - field->max_length=NAME_LEN; - end=strmov(field->name,"Database"); - if (wild && wild[0]) - strxmov(end," (",wild,")",NullS); - field_list.push_back(field); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - if (mysql_find_files(thd,&files,NullS,mysql_data_home,wild,1)) - DBUG_RETURN(1); - List_iterator_fast it(files); - - while ((file_name=it++)) - { -#ifndef NO_EMBEDDED_ACCESS_CHECKS - if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || - acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) || - (grant_option && !check_grant_db(thd, file_name))) -#endif - { - protocol->prepare_for_resend(); - protocol->store(file_name, system_charset_info); - if (protocol->write()) - DBUG_RETURN(-1); - } - } - send_eof(thd); - DBUG_RETURN(0); -} - - /*************************************************************************** List all open tables in a database ***************************************************************************/ @@ -132,70 +84,6 @@ int mysqld_show_open_tables(THD *thd,const char *wild) } -/*************************************************************************** -** List all tables in a database (fast version) -** A table is a .frm file in the current databasedir -***************************************************************************/ - -int mysqld_show_tables(THD *thd, const char *db, const char *wild, - bool show_type) -{ - Item_string *field=new Item_string("",0,thd->charset()); - List field_list; - char path[FN_LEN],*end; - List files; - char *file_name; - Protocol *protocol= thd->protocol; - uint len; - DBUG_ENTER("mysqld_show_tables"); - - field->name=(char*) thd->alloc(20+(uint) strlen(db)+ - (wild ? (uint) strlen(wild)+4:0)); - end=strxmov(field->name,"Tables_in_",db,NullS); - if (wild && wild[0]) - strxmov(end," (",wild,")",NullS); - field->max_length=NAME_LEN; - (void) my_snprintf(path, FN_LEN, "%s/%s", mysql_data_home, db); - end= path + (len= unpack_dirname(path,path)); - len= FN_LEN - len; - field_list.push_back(field); - if (show_type) - field_list.push_back(new Item_empty_string("Table_type", 10)); - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - if (mysql_find_files(thd,&files,db,path,wild,0)) - DBUG_RETURN(-1); - List_iterator_fast it(files); - while ((file_name=it++)) - { - protocol->prepare_for_resend(); - protocol->store(file_name, system_charset_info); - if (show_type) - { - my_snprintf(end, len, "/%s%s", file_name, reg_ext); - switch (mysql_frm_type(path)) - { - case FRMTYPE_ERROR: - protocol->store("ERROR", system_charset_info); - break; - case FRMTYPE_TABLE: - protocol->store("BASE TABLE", system_charset_info); - break; - case FRMTYPE_VIEW: - protocol->store("VIEW", system_charset_info); - break; - default: - DBUG_ASSERT(0); // this should be impossible - } - } - if (protocol->write()) - DBUG_RETURN(-1); - } - send_eof(thd); - DBUG_RETURN(0); -} - /*************************************************************************** ** List all table types supported ***************************************************************************/ @@ -482,211 +370,6 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, } -/*************************************************************************** - Extended version of mysqld_show_tables -***************************************************************************/ - -int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) -{ - Item *item; - List files; - List field_list; - char path[FN_LEN]; - char *file_name; - TABLE *table; - Protocol *protocol= thd->protocol; - TIME time; - int res; - DBUG_ENTER("mysqld_extend_show_tables"); - - (void) sprintf(path,"%s/%s",mysql_data_home,db); - (void) unpack_dirname(path,path); - field_list.push_back(item=new Item_empty_string("Name",NAME_LEN)); - field_list.push_back(item=new Item_empty_string("Engine",10)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Version", (longlong) 0, 21)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Row_format",10)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Rows",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Avg_row_length",(int32) 0,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Data_length",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Max_data_length",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Index_length",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Data_free",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Auto_increment",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_datetime("Create_time")); - item->maybe_null=1; - field_list.push_back(item=new Item_datetime("Update_time")); - item->maybe_null=1; - field_list.push_back(item=new Item_datetime("Check_time")); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Collation",32)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Checksum",(longlong) 1,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Create_options",255)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Comment",80)); - item->maybe_null=1; - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - if (mysql_find_files(thd,&files,db,path,wild,0)) - DBUG_RETURN(-1); - List_iterator_fast it(files); - while ((file_name=it++)) - { - TABLE_LIST table_list; - bzero((char*) &table_list,sizeof(table_list)); - protocol->prepare_for_resend(); - protocol->store(file_name, system_charset_info); - table_list.db=(char*) db; - table_list.real_name= table_list.alias= file_name; - table_list.select_lex= &thd->lex->select_lex; - if (lower_case_table_names) - my_casedn_str(files_charset_info, file_name); - if ((res= open_and_lock_tables(thd, &table_list))) - { - for (uint i=2 ; i < field_list.elements ; i++) - protocol->store_null(); - // Send error to Comment field if possible - if (res < 0) - { - protocol->store(thd->net.last_error, system_charset_info); - thd->clear_error(); - } - else - DBUG_RETURN(1); - } - else if (table_list.view) - { - for (uint i= 2; i < field_list.elements; i++) - protocol->store_null(); - protocol->store("view", system_charset_info); - } - else - { - const char *str; - handler *file= (table= table_list.table)->file; - file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK); - protocol->store(file->table_type(), system_charset_info); - protocol->store((ulonglong) table->frm_version); - str= ((table->db_options_in_use & HA_OPTION_COMPRESS_RECORD) ? - "Compressed" : - (table->db_options_in_use & HA_OPTION_PACK_RECORD) ? - "Dynamic" : "Fixed"); - protocol->store(str, system_charset_info); - protocol->store((ulonglong) file->records); - protocol->store((ulonglong) file->mean_rec_length); - protocol->store((ulonglong) file->data_file_length); - if (file->max_data_file_length) - protocol->store((ulonglong) file->max_data_file_length); - else - protocol->store_null(); - protocol->store((ulonglong) file->index_file_length); - protocol->store((ulonglong) file->delete_length); - if (table->found_next_number_field) - { - table->next_number_field=table->found_next_number_field; - table->next_number_field->reset(); - file->update_auto_increment(); - protocol->store(table->next_number_field->val_int()); - table->next_number_field=0; - } - else - protocol->store_null(); - if (!file->create_time) - protocol->store_null(); - else - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, file->create_time); - protocol->store(&time); - } - if (!file->update_time) - protocol->store_null(); - else - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, file->update_time); - protocol->store(&time); - } - if (!file->check_time) - protocol->store_null(); - else - { - thd->variables.time_zone->gmt_sec_to_TIME(&time, file->check_time); - protocol->store(&time); - } - str= (table->table_charset ? table->table_charset->name : "default"); - protocol->store(str, system_charset_info); - if (file->table_flags() & HA_HAS_CHECKSUM) - protocol->store((ulonglong)file->checksum()); - else - protocol->store_null(); // Checksum - { - char option_buff[350],*ptr; - ptr=option_buff; - if (table->min_rows) - { - ptr=strmov(ptr," min_rows="); - ptr=longlong10_to_str(table->min_rows,ptr,10); - } - if (table->max_rows) - { - ptr=strmov(ptr," max_rows="); - ptr=longlong10_to_str(table->max_rows,ptr,10); - } - if (table->avg_row_length) - { - ptr=strmov(ptr," avg_row_length="); - ptr=longlong10_to_str(table->avg_row_length,ptr,10); - } - if (table->db_create_options & HA_OPTION_PACK_KEYS) - ptr=strmov(ptr," pack_keys=1"); - if (table->db_create_options & HA_OPTION_NO_PACK_KEYS) - ptr=strmov(ptr," pack_keys=0"); - if (table->db_create_options & HA_OPTION_CHECKSUM) - ptr=strmov(ptr," checksum=1"); - if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) - ptr=strmov(ptr," delay_key_write=1"); - if (table->row_type != ROW_TYPE_DEFAULT) - ptr=strxmov(ptr, " row_format=", ha_row_type[(uint) table->row_type], - NullS); - if (file->raid_type) - { - char buff[100]; - sprintf(buff," raid_type=%s raid_chunks=%d raid_chunksize=%ld", - my_raid_type(file->raid_type), file->raid_chunks, file->raid_chunksize/RAID_BLOCK_SIZE); - ptr=strmov(ptr,buff); - } - protocol->store(option_buff+1, - (ptr == option_buff ? 0 : (uint) (ptr-option_buff)-1) - , system_charset_info); - } - { - char *comment=table->file->update_table_comment(table->comment); - protocol->store(comment, system_charset_info); - if (comment != table->comment) - my_free(comment,MYF(0)); - } - } - close_thread_tables(thd, 0); - if (protocol->write()) - DBUG_RETURN(-1); - } - send_eof(thd); - DBUG_RETURN(0); -} - - /*************************************************************************** ** List all columns in a table_list->real_name ***************************************************************************/ @@ -1046,103 +729,6 @@ mysqld_show_logs(THD *thd) } -int -mysqld_show_keys(THD *thd, TABLE_LIST *table_list) -{ - TABLE *table; - Protocol *protocol= thd->protocol; - DBUG_ENTER("mysqld_show_keys"); - DBUG_PRINT("enter",("db: %s table: %s",table_list->db, - table_list->real_name)); - - if (!(table = open_ltable(thd, table_list, TL_UNLOCK))) - { - send_error(thd); - DBUG_RETURN(1); - } - - List field_list; - Item *item; - field_list.push_back(new Item_empty_string("Table",NAME_LEN)); - field_list.push_back(new Item_return_int("Non_unique",1, MYSQL_TYPE_TINY)); - field_list.push_back(new Item_empty_string("Key_name",NAME_LEN)); - field_list.push_back(new Item_return_int("Seq_in_index",2, MYSQL_TYPE_TINY)); - field_list.push_back(new Item_empty_string("Column_name",NAME_LEN)); - field_list.push_back(item=new Item_empty_string("Collation",1)); - item->maybe_null=1; - field_list.push_back(item=new Item_int("Cardinality",0,21)); - item->maybe_null=1; - field_list.push_back(item=new Item_return_int("Sub_part",3, - MYSQL_TYPE_TINY)); - item->maybe_null=1; - field_list.push_back(item=new Item_empty_string("Packed",10)); - item->maybe_null=1; - field_list.push_back(new Item_empty_string("Null",3)); - field_list.push_back(new Item_empty_string("Index_type",16)); - field_list.push_back(new Item_empty_string("Comment",255)); - item->maybe_null=1; - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - KEY *key_info=table->key_info; - table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); - for (uint i=0 ; i < table->keys ; i++,key_info++) - { - KEY_PART_INFO *key_part= key_info->key_part; - const char *str; - for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) - { - protocol->prepare_for_resend(); - protocol->store(table->table_name, system_charset_info); - protocol->store_tiny((longlong) ((key_info->flags & HA_NOSAME) ? 0 :1)); - protocol->store(key_info->name, system_charset_info); - protocol->store_tiny((longlong) (j+1)); - str=(key_part->field ? key_part->field->field_name : - "?unknown field?"); - protocol->store(str, system_charset_info); - if (table->file->index_flags(i, j, 0) & HA_READ_ORDER) - protocol->store(((key_part->key_part_flag & HA_REVERSE_SORT) ? - "D" : "A"), 1, system_charset_info); - else - protocol->store_null(); /* purecov: inspected */ - KEY *key=table->key_info+i; - if (key->rec_per_key[j]) - { - ha_rows records=(table->file->records / key->rec_per_key[j]); - protocol->store((ulonglong) records); - } - else - protocol->store_null(); - - /* Check if we have a key part that only uses part of the field */ - if (!(key_info->flags & HA_FULLTEXT) && (!key_part->field || - key_part->length != table->field[key_part->fieldnr-1]->key_length())) - protocol->store_tiny((longlong) key_part->length); - else - protocol->store_null(); - protocol->store_null(); // No pack_information yet - - /* Null flag */ - uint flags= key_part->field ? key_part->field->flags : 0; - char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); - protocol->store((const char*) pos, system_charset_info); - protocol->store(table->file->index_type(i), system_charset_info); - /* Comment */ - if (!table->keys_in_use.is_set(i)) - protocol->store("disabled",8, system_charset_info); - else - protocol->store("", 0, system_charset_info); - if (protocol->write()) - DBUG_RETURN(1); /* purecov: inspected */ - } - } - send_eof(thd); - DBUG_RETURN(0); -} - - /**************************************************************************** Return only fields for API mysql_list_fields Use "show table wildcard" in mysql instead of this @@ -1816,112 +1402,6 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) Status functions *****************************************************************************/ -static bool write_collation(Protocol *protocol, CHARSET_INFO *cs) -{ - protocol->prepare_for_resend(); - protocol->store(cs->name, system_charset_info); - protocol->store(cs->csname, system_charset_info); - protocol->store_short((longlong) cs->number); - protocol->store((cs->state & MY_CS_PRIMARY) ? "Yes" : "",system_charset_info); - protocol->store((cs->state & MY_CS_COMPILED)? "Yes" : "",system_charset_info); - protocol->store_short((longlong) cs->strxfrm_multiply); - return protocol->write(); -} - -int mysqld_show_collations(THD *thd, const char *wild) -{ - char buff[8192]; - String packet2(buff,sizeof(buff),thd->charset()); - List field_list; - CHARSET_INFO **cs; - Protocol *protocol= thd->protocol; - - DBUG_ENTER("mysqld_show_charsets"); - - field_list.push_back(new Item_empty_string("Collation",30)); - field_list.push_back(new Item_empty_string("Charset",30)); - field_list.push_back(new Item_return_int("Id",11, FIELD_TYPE_SHORT)); - field_list.push_back(new Item_empty_string("Default",30)); - field_list.push_back(new Item_empty_string("Compiled",30)); - field_list.push_back(new Item_return_int("Sortlen",3, FIELD_TYPE_SHORT)); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) - { - CHARSET_INFO **cl; - if (!cs[0] || !(cs[0]->state & MY_CS_AVAILABLE) || - !(cs[0]->state & MY_CS_PRIMARY)) - continue; - for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) - { - if (!cl[0] || !(cl[0]->state & MY_CS_AVAILABLE) || - !my_charset_same(cs[0],cl[0])) - continue; - if (!(wild && wild[0] && - wild_case_compare(system_charset_info,cl[0]->name,wild))) - { - if (write_collation(protocol, cl[0])) - goto err; - } - } - } - send_eof(thd); - DBUG_RETURN(0); -err: - DBUG_RETURN(1); -} - -static bool write_charset(Protocol *protocol, CHARSET_INFO *cs) -{ - protocol->prepare_for_resend(); - protocol->store(cs->csname, system_charset_info); - protocol->store(cs->comment ? cs->comment : "", system_charset_info); - protocol->store(cs->name, system_charset_info); - protocol->store_short((longlong) cs->mbmaxlen); - return protocol->write(); -} - -int mysqld_show_charsets(THD *thd, const char *wild) -{ - char buff[8192]; - String packet2(buff,sizeof(buff),thd->charset()); - List field_list; - CHARSET_INFO **cs; - Protocol *protocol= thd->protocol; - - DBUG_ENTER("mysqld_show_charsets"); - - field_list.push_back(new Item_empty_string("Charset",30)); - field_list.push_back(new Item_empty_string("Description",60)); - field_list.push_back(new Item_empty_string("Default collation",60)); - field_list.push_back(new Item_return_int("Maxlen",3, FIELD_TYPE_SHORT)); - - if (protocol->send_fields(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(1); - - for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) - { - if (cs[0] && (cs[0]->state & MY_CS_PRIMARY) && - (cs[0]->state & MY_CS_AVAILABLE) && - !(wild && wild[0] && - wild_case_compare(system_charset_info,cs[0]->csname,wild))) - { - if (write_charset(protocol, cs[0])) - goto err; - } - } - send_eof(thd); - DBUG_RETURN(0); -err: - DBUG_RETURN(1); -} - - - int mysqld_show(THD *thd, const char *wild, show_var_st *variables, enum enum_var_type value_type, pthread_mutex_t *mutex, @@ -2261,6 +1741,1662 @@ void calc_sum_of_all_status(STATUS_VAR *to) } +LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, + const char* str, uint length, + bool allocate_lex_string) +{ + MEM_ROOT *mem= thd->mem_root; + if (allocate_lex_string) + lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING)); + lex_str->str= strmake_root(mem, str, length); + lex_str->length= length; + return lex_str; +} + + +/* INFORMATION_SCHEMA name */ +LEX_STRING information_schema_name= {(char*)"information_schema", 18}; +extern ST_SCHEMA_TABLE schema_tables[]; + +typedef struct st_index_field_values +{ + const char *db_value, *table_value; +} INDEX_FIELD_VALUES; + + +void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values) +{ + const char *wild= lex->wild ? lex->wild->ptr() : NullS; + switch (lex->orig_sql_command) { + case SQLCOM_SHOW_DATABASES: + index_field_values->db_value= wild; + break; + case SQLCOM_SHOW_TABLES: + case SQLCOM_SHOW_TABLE_STATUS: + index_field_values->db_value= lex->current_select->db; + index_field_values->table_value= wild; + break; + default: + index_field_values->db_value= NullS; + index_field_values->table_value= NullS; + break; + } +} + + +int make_table_list(THD *thd, SELECT_LEX *sel, + char *db, char *table) +{ + Table_ident *table_ident; + LEX_STRING ident_db, ident_table; + ident_db.str= db; + ident_db.length= strlen(db); + ident_table.str= table; + ident_table.length= strlen(table); + table_ident= new Table_ident(thd, ident_db, ident_table, 1); + sel->init_query(); + if(!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ, + (List *) 0, (List *) 0)) + return 1; + return 0; +} + + +bool uses_only_table_name_fields(Item *item, TABLE_LIST *table) +{ + if (item->type() == Item::FUNC_ITEM) + { + Item_func *item_func= (Item_func*)item; + Item **child; + Item **item_end= (item_func->arguments()) + item_func->argument_count(); + for (child= item_func->arguments(); child != item_end; child++) + if (!uses_only_table_name_fields(*child, table)) + return 0; + return 1; + } + else if (item->type() == Item::FIELD_ITEM) + { + Item_field *item_field= (Item_field*)item; + CHARSET_INFO *cs= system_charset_info; + ST_SCHEMA_TABLE *schema_table= table->schema_table; + ST_FIELD_INFO *field_info= schema_table->fields_info; + const char *field_name1= field_info[schema_table->idx_field1].field_name; + const char *field_name2= field_info[schema_table->idx_field2].field_name; + if(table->table != item_field->field->table || + (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1), + (uchar *) item_field->field_name, + strlen(item_field->field_name)) && + cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2), + (uchar *) item_field->field_name, + strlen(item_field->field_name)))) + return 0; + else + return 1; + } + else + return 1; +} + + +static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table) +{ + if (!cond) + return (COND*) 0; + if (cond->type() == Item::COND_ITEM) + { + if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) + { + /* Create new top level AND item */ + Item_cond_and *new_cond=new Item_cond_and; + if (!new_cond) + return (COND*) 0; + List_iterator li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + Item *fix= make_cond_for_info_schema(item, table); + if (fix) + new_cond->argument_list()->push_back(fix); + } + switch (new_cond->argument_list()->elements) { + case 0: + return (COND*) 0; + case 1: + return new_cond->argument_list()->head(); + default: + new_cond->quick_fix_field(); + return new_cond; + } + } + else + { // Or list + Item_cond_or *new_cond=new Item_cond_or; + if (!new_cond) + return (COND*) 0; + List_iterator li(*((Item_cond*) cond)->argument_list()); + Item *item; + while ((item=li++)) + { + Item *fix=make_cond_for_info_schema(item, table); + if (!fix) + return (COND*) 0; + new_cond->argument_list()->push_back(fix); + } + new_cond->quick_fix_field(); + new_cond->top_level_item(); + return new_cond; + } + } + + if (!uses_only_table_name_fields(cond, table)) + return (COND*) 0; + return cond; +} + + +int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) +{ + LEX *lex= thd->lex; + TABLE *table= tables->table; + SELECT_LEX *select_lex= &lex->select_lex; + ST_SCHEMA_TABLE *schema_table= tables->schema_table; + DBUG_ENTER("fill_schema_tables"); + + SELECT_LEX *lsel= tables->schema_select_lex; + if (lsel) + { + TABLE *old_open_tables= thd->open_tables; + TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first; + lex->all_selects_list= lsel; + int res= open_and_lock_tables(thd, show_table_list); + if (schema_table->process_table(thd, show_table_list, + table, res, show_table_list->db, + show_table_list->real_name)) + { + DBUG_RETURN(1); + } + close_thread_tables(thd, 0, 0, old_open_tables); + show_table_list->table= 0; + lex->all_selects_list= select_lex; + DBUG_RETURN(0); + } + + SELECT_LEX sel; + INDEX_FIELD_VALUES idx_field_vals; + char path[FN_REFLEN], *end, *base_name, *file_name; + uint len; + List bases; + lex->all_selects_list= &sel; + enum enum_schema_tables schema_table_idx= + (enum enum_schema_tables) (schema_table - &schema_tables[0]); + thr_lock_type lock_type= TL_UNLOCK; + if (schema_table_idx == SCH_TABLES) + lock_type= TL_READ; + get_index_field_values(lex, &idx_field_vals); + if (mysql_find_files(thd, &bases, NullS, mysql_data_home, + idx_field_vals.db_value, 1)) + return 1; + List_iterator_fast it(bases); + COND *partial_cond= make_cond_for_info_schema(cond, tables); + while ((base_name=it++) || + /* + generate error for non existing database. + (to save old behaviour for SHOW TABLES FROM db) + */ + ((lex->orig_sql_command == SQLCOM_SHOW_TABLES || + lex->orig_sql_command == SQLCOM_SHOW_TABLE_STATUS) && + (base_name= select_lex->db) && !bases.elements)) + { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (!check_access(thd,SELECT_ACL, base_name, &thd->col_access,0,1) || + thd->master_access & (DB_ACLS | SHOW_DB_ACL) || + acl_get(thd->host, thd->ip, thd->priv_user, base_name,0) || + (grant_option && !check_grant_db(thd, base_name))) +#endif + { + List files; + (void) sprintf(path,"%s/%s",mysql_data_home,base_name); + end= path + (len= unpack_dirname(path,path)); + len= FN_LEN - len; + if (mysql_find_files(thd, &files, base_name, + path, idx_field_vals.table_value, 0)) + DBUG_RETURN(1); + + List_iterator_fast it(files); + while ((file_name=it++)) + { + restore_record(table, default_values); + table->field[schema_table->idx_field1]-> + store(base_name, strlen(base_name), system_charset_info); + table->field[schema_table->idx_field2]-> + store(file_name, strlen(file_name),system_charset_info); + if (!partial_cond || partial_cond->val_int()) + { + if (schema_table_idx == SCH_TABLE_NAMES) + { + if (lex->verbose || lex->orig_sql_command == SQLCOM_END) + { + my_snprintf(end, len, "/%s%s", file_name, reg_ext); + switch (mysql_frm_type(path)) + { + case FRMTYPE_ERROR: + table->field[3]->store("ERROR", 5, system_charset_info); + break; + case FRMTYPE_TABLE: + table->field[3]->store("BASE TABLE", 10, system_charset_info); + break; + case FRMTYPE_VIEW: + table->field[3]->store("VIEW", 4, system_charset_info); + break; + default: + DBUG_ASSERT(0); + } + } + table->file->write_row(table->record[0]); + } + else + { + int res; + TABLE *old_open_tables= thd->open_tables; + if (make_table_list(thd, &sel, base_name, file_name)) + DBUG_RETURN(1); + TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first; + show_table_list->lock_type= lock_type; + res= open_and_lock_tables(thd, show_table_list); + if (schema_table->process_table(thd, show_table_list, table, + res, base_name, file_name)) + { + DBUG_RETURN(1); + } + close_thread_tables(thd, 0, 0, old_open_tables); + } + } + } + } + } + lex->all_selects_list= select_lex; + DBUG_RETURN(0); +} + + +int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) +{ + char path[FN_REFLEN],*end; + bool found_libchar; + INDEX_FIELD_VALUES idx_field_vals; + List files; + char *file_name; + uint length; + HA_CREATE_INFO create; + TABLE *table= tables->table; + + get_index_field_values(thd->lex, &idx_field_vals); + if (mysql_find_files(thd, &files, NullS, mysql_data_home, + idx_field_vals.db_value, 1)) + return 1; + List_iterator_fast it(files); + while ((file_name=it++)) + { +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (thd->master_access & (DB_ACLS | SHOW_DB_ACL) || + acl_get(thd->host, thd->ip, thd->priv_user, file_name,0) || + (grant_option && !check_grant_db(thd, file_name))) +#endif + { + (void) sprintf(path,"%s/%s",mysql_data_home, file_name); + length=unpack_dirname(path,path); // Convert if not unix + found_libchar= 0; + if (length && path[length-1] == FN_LIBCHAR) + { + found_libchar= 1; + path[length-1]=0; // remove ending '\' + } + + if (found_libchar) + path[length-1]= FN_LIBCHAR; + strmov(path+length, MY_DB_OPT_FILE); + load_db_opt(thd, path, &create); + restore_record(table, default_values); + table->field[1]->store(file_name, strlen(file_name), system_charset_info); + table->field[2]->store(create.default_table_charset->name, + strlen(create.default_table_charset->name), + system_charset_info); + table->file->write_row(table->record[0]); + } + } + return 0; +} + + +int get_schema_tables_record(THD *thd, struct st_table_list *tables, + TABLE *table, int res, + const char *base_name, const char *file_name) +{ + const char *tmp_buff; + TIME time; + CHARSET_INFO *cs= system_charset_info; + + DBUG_ENTER("get_schema_tables_record"); + restore_record(table, default_values); + if (res > 0) + { + DBUG_RETURN(1); + } + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(file_name, strlen(file_name), cs); + if (res < 0 || tables->view) + { + table->field[3]->store("VIEW", 4, cs); + table->field[20]->store("view", 4, cs); + if (res) + thd->clear_error(); + } + else + { + TABLE *show_table= tables->table; + handler *file= show_table->file; + file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_NO_LOCK); + table->field[3]->store("BASE TABLE", 10, cs); + for (int i= 4; i < 20; i++) + { + if ((i > 12 && i < 17) || i == 18) + continue; + table->field[i]->set_notnull(); + } + tmp_buff= file->table_type(); + table->field[4]->store(tmp_buff, strlen(tmp_buff), cs); + table->field[5]->store((longlong) show_table->frm_version); + tmp_buff= ((show_table->db_options_in_use & + HA_OPTION_COMPRESS_RECORD) ? "Compressed" : + (show_table->db_options_in_use & HA_OPTION_PACK_RECORD) ? + "Dynamic" : "Fixed"); + table->field[6]->store(tmp_buff, strlen(tmp_buff), cs); + table->field[7]->store((longlong) file->records); + table->field[8]->store((longlong) file->mean_rec_length); + table->field[9]->store((longlong) file->data_file_length); + if (file->max_data_file_length) + { + table->field[10]->store((longlong) file->max_data_file_length); + } + table->field[11]->store((longlong) file->index_file_length); + table->field[12]->store((longlong) file->delete_length); + if (table->found_next_number_field) + { + show_table->next_number_field=show_table->found_next_number_field; + show_table->next_number_field->reset(); + file->update_auto_increment(); + table->field[13]->store((longlong) show_table-> + next_number_field->val_int()); + table->field[13]->set_notnull(); + show_table->next_number_field=0; + } + if (file->create_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, + file->create_time); + table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[14]->set_notnull(); + } + if (file->update_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, + file->update_time); + table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[15]->set_notnull(); + } + if (file->check_time) + { + thd->variables.time_zone->gmt_sec_to_TIME(&time, file->check_time); + table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + table->field[16]->set_notnull(); + } + tmp_buff= (show_table->table_charset ? show_table-> + table_charset->name : "default"); + table->field[17]->store(tmp_buff, strlen(tmp_buff), cs); + if (file->table_flags() & HA_HAS_CHECKSUM) + { + table->field[18]->store((longlong) file->checksum()); + table->field[18]->set_notnull(); + } + + char option_buff[350],*ptr; + ptr=option_buff; + if (show_table->min_rows) + { + ptr=strmov(ptr," min_rows="); + ptr=longlong10_to_str(show_table->min_rows,ptr,10); + } + if (show_table->max_rows) + { + ptr=strmov(ptr," max_rows="); + ptr=longlong10_to_str(show_table->max_rows,ptr,10); + } + if (show_table->avg_row_length) + { + ptr=strmov(ptr," avg_row_length="); + ptr=longlong10_to_str(show_table->avg_row_length,ptr,10); + } + if (show_table->db_create_options & HA_OPTION_PACK_KEYS) + ptr=strmov(ptr," pack_keys=1"); + if (show_table->db_create_options & HA_OPTION_NO_PACK_KEYS) + ptr=strmov(ptr," pack_keys=0"); + if (show_table->db_create_options & HA_OPTION_CHECKSUM) + ptr=strmov(ptr," checksum=1"); + if (show_table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) + ptr=strmov(ptr," delay_key_write=1"); + if (show_table->row_type != ROW_TYPE_DEFAULT) + ptr=strxmov(ptr, " row_format=", + ha_row_type[(uint) show_table->row_type], + NullS); + if (file->raid_type) + { + char buff[100]; + sprintf(buff," raid_type=%s raid_chunks=%d raid_chunksize=%ld", + my_raid_type(file->raid_type), file->raid_chunks, + file->raid_chunksize/RAID_BLOCK_SIZE); + ptr=strmov(ptr,buff); + } + table->field[19]->store(option_buff+1, + (ptr == option_buff ? 0 : + (uint) (ptr-option_buff)-1), cs); + + char *comment= show_table->file-> + update_table_comment(show_table->comment); + table->field[20]->store(comment, strlen(comment), cs); + if (comment != show_table->comment) + my_free(comment,MYF(0)); + } + table->file->write_row(table->record[0]); + DBUG_RETURN(0); +} + + +int get_schema_column_record(THD *thd, struct st_table_list *tables, + TABLE *table, int res, + const char *base_name, const char *file_name) +{ + TIME time; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_column_record"); + if (res) + { + DBUG_RETURN(1); + } + + TABLE *show_table= tables->table; + handler *file= show_table->file; + file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); + restore_record(show_table, default_values); + Field **ptr,*field; + int count= 0; + for (ptr=show_table->field; (field= *ptr) ; ptr++) + { + if (!wild || !wild[0] || + !wild_case_compare(system_charset_info, field->field_name,wild)) + { + uint tmp_length; + char *tmp_buff; + byte *pos; + uint flags=field->flags; + char tmp[MAX_FIELD_WIDTH]; + char tmp1[MAX_FIELD_WIDTH]; + String type(tmp,sizeof(tmp), system_charset_info); + char tmp_buffer[128]; + count++; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(file_name, strlen(file_name), cs); + table->field[3]->store(field->field_name, strlen(field->field_name), + cs); + table->field[4]->store((longlong) count); + field->sql_type(type); + table->field[11]->store(type.ptr(), type.length(), cs); + tmp_buff= strchr(type.ptr(),'('); + table->field[5]->store(type.ptr(), + (tmp_buff ? tmp_buff - type.ptr() : + type.length()), cs); + + if (show_table->timestamp_field == field && + field->unireg_check != Field::TIMESTAMP_UN_FIELD) + { + table->field[15]->store("CURRENT_TIMESTAMP", 17, cs); + table->field[15]->set_notnull(); + } + else if (field->unireg_check != Field::NEXT_NUMBER && + !field->is_null() && + !(field->flags & NO_DEFAULT_VALUE_FLAG)) + { + String def(tmp1,sizeof(tmp1), cs); + type.set(tmp, sizeof(tmp), field->charset()); + field->val_str(&type); + uint dummy_errors; + def.copy(type.ptr(), type.length(), type.charset(), cs, &dummy_errors); + table->field[15]->store(def.ptr(), def.length(), def.charset()); + table->field[15]->set_notnull(); + } + else if (field->unireg_check == Field::NEXT_NUMBER || + field->maybe_null()) + table->field[15]->set_null(); // Null as default + else + { + table->field[15]->store("",0, cs); + table->field[15]->set_notnull(); + } + + pos=(byte*) ((flags & NOT_NULL_FLAG) && + field->type() != FIELD_TYPE_TIMESTAMP ? + "" : "YES"); + table->field[13]->store((const char*) pos, + strlen((const char*) pos), cs); + if (field->has_charset()) + { + table->field[6]->store((longlong) field->field_length/ + field->charset()->mbmaxlen); + } + table->field[7]->store((longlong) field->field_length); + table->field[8]->store((longlong) field->pack_length()); + table->field[9]->store((longlong) field->decimals()); + if (field->has_charset()) + { + pos=(byte*) field->charset()->csname; + table->field[10]->store((const char*) pos, + strlen((const char*) pos), cs); + table->field[10]->set_notnull(); + pos=(byte*) field->charset()->name; + table->field[12]->store((const char*) pos, + strlen((const char*) pos), cs); + table->field[12]->set_notnull(); + } + pos=(byte*) ((field->flags & PRI_KEY_FLAG) ? "PRI" : + (field->flags & UNIQUE_KEY_FLAG) ? "UNI" : + (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":""); + table->field[14]->store((const char*) pos, + strlen((const char*) pos), cs); + char *end=tmp; + if (field->unireg_check == Field::NEXT_NUMBER) + end=strmov(tmp,"auto_increment"); + table->field[16]->store(tmp, (uint) (end-tmp), cs); + if (thd->lex->verbose) + { + end=tmp; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + uint col_access; + check_access(thd,SELECT_ACL | EXTRA_ACL, base_name, + &tables->grant.privilege, 0, 0); + col_access= get_column_grant(thd, &tables->grant, tables->db, + tables->real_name, + field->field_name) & COL_ACLS; + for (uint bitnr=0; col_access ; col_access>>=1,bitnr++) + { + if (col_access & 1) + { + *end++=','; + end=strmov(end,grant_types.type_names[bitnr]); + } + } +#else + end=strmov(end,""); +#endif + table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs); + table->field[18]->store(field->comment.str, field->comment.length, cs); + } + table->file->write_row(table->record[0]); + } + } + DBUG_RETURN(0); +} + + + +int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond) +{ + CHARSET_INFO **cs; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + TABLE *table= tables->table; + CHARSET_INFO *scs= system_charset_info; + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) + { + CHARSET_INFO *tmp_cs= cs[0]; + if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) && + (tmp_cs->state & MY_CS_AVAILABLE) && + !(wild && wild[0] && + wild_case_compare(scs, tmp_cs->csname,wild))) + { + restore_record(table, default_values); + table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs); + table->field[1]->store(tmp_cs->comment ? tmp_cs->comment : "", + strlen(tmp_cs->comment ? tmp_cs->comment : ""), + scs); + table->field[2]->store(tmp_cs->name, strlen(tmp_cs->name), scs); + table->field[3]->store((longlong) tmp_cs->mbmaxlen); + table->file->write_row(table->record[0]); + } + } + return 0; +} + + +int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond) +{ + CHARSET_INFO **cs; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + TABLE *table= tables->table; + CHARSET_INFO *scs= system_charset_info; + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) + { + CHARSET_INFO **cl; + CHARSET_INFO *tmp_cs= cs[0]; + if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || + !(tmp_cs->state & MY_CS_PRIMARY)) + continue; + for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) + { + CHARSET_INFO *tmp_cl= cl[0]; + if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || + !my_charset_same(tmp_cs, tmp_cl)) + continue; + if (!(wild && wild[0] && + wild_case_compare(scs, tmp_cl->name,wild))) + { + const char *tmp_buff; + restore_record(table, default_values); + table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs); + table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs); + table->field[2]->store((longlong) tmp_cl->number); + tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : ""; + table->field[3]->store(tmp_buff, strlen(tmp_buff), scs); + tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : ""; + table->field[4]->store(tmp_buff, strlen(tmp_buff), scs); + table->field[5]->store((longlong) tmp_cl->strxfrm_multiply); + table->file->write_row(table->record[0]); + } + } + } + return 0; +} + + +int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond) +{ + CHARSET_INFO **cs; + const char *wild= NullS; + TABLE *table= tables->table; + CHARSET_INFO *scs= system_charset_info; + for ( cs= all_charsets ; cs < all_charsets+255 ; cs++ ) + { + CHARSET_INFO **cl; + CHARSET_INFO *tmp_cs= cs[0]; + if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) || + !(tmp_cs->state & MY_CS_PRIMARY)) + continue; + for ( cl= all_charsets; cl < all_charsets+255 ;cl ++) + { + CHARSET_INFO *tmp_cl= cl[0]; + if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) || + !my_charset_same(tmp_cs,tmp_cl)) + continue; + restore_record(table, default_values); + table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs); + table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs); + table->file->write_row(table->record[0]); + } + } + return 0; +} + + +void store_schema_proc(THD *thd, TABLE *table, + TABLE *proc_table, + const char *wild) +{ + String tmp_string; + TIME time; + LEX *lex= thd->lex; + CHARSET_INFO *cs= system_charset_info; + restore_record(table, default_values); + if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC && + proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE || + lex->orig_sql_command == SQLCOM_SHOW_STATUS_FUNC && + proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION || + lex->orig_sql_command == SQLCOM_END) + { + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[1], &tmp_string); + if (!wild || !wild[0] || !wild_compare(tmp_string.ptr(), wild, 0)) + { + table->field[3]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[0], &tmp_string); + table->field[2]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[2], &tmp_string); + table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[3], &tmp_string); + table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[5], &tmp_string); + table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[6], &tmp_string); + table->field[10]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[7], &tmp_string); + table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[9], &tmp_string); + table->field[6]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[10], &tmp_string); + table->field[8]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[11], &tmp_string); + table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs); + bzero((char *)&time, sizeof(time)); + ((Field_timestamp *) proc_table->field[12])->get_time(&time); + table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + bzero((char *)&time, sizeof(time)); + ((Field_timestamp *) proc_table->field[13])->get_time(&time); + table->field[13]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); + get_field(thd->mem_root, proc_table->field[14], &tmp_string); + table->field[16]->store(tmp_string.ptr(), tmp_string.length(), cs); + tmp_string.length(0); + get_field(thd->mem_root, proc_table->field[15], &tmp_string); + table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); + table->field[7]->store("SQL", 3, cs); + table->field[9]->store("SQL", 3, cs); + table->file->write_row(table->record[0]); + } + } +} + + +int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) +{ + TABLE *proc_table; + TABLE_LIST proc_tables; + const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; + int res= 0; + TABLE *table= tables->table, *old_open_tables= thd->open_tables; + DBUG_ENTER("fill_schema_proc"); + + bzero((char*) &proc_tables,sizeof(proc_tables)); + proc_tables.db= (char*) "mysql"; + proc_tables.real_name= proc_tables.alias= (char*) "proc"; + proc_tables.lock_type= TL_READ; + if (!(proc_table= open_ltable(thd, &proc_tables, TL_READ))) + { + DBUG_RETURN(1); + } + proc_table->file->ha_index_init(0); + if ((res= proc_table->file->index_first(proc_table->record[0]))) + { + res= (res == HA_ERR_END_OF_FILE) ? 0 : 1; + goto err; + } + store_schema_proc(thd, table, proc_table, wild); + while (!proc_table->file->index_next(proc_table->record[0])) + store_schema_proc(thd, table, proc_table, wild); + +err: + proc_table->file->ha_index_end(); + close_thread_tables(thd, 0, 0, old_open_tables); + DBUG_RETURN(res); +} + + +int get_schema_stat_record(THD *thd, struct st_table_list *tables, + TABLE *table, int res, + const char *base_name, const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_stat_record"); + if (!res) + { + TABLE *show_table= tables->table; + KEY *key_info=show_table->key_info; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + for (uint i=0 ; i < show_table->keys ; i++,key_info++) + { + KEY_PART_INFO *key_part= key_info->key_part; + const char *str; + for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) + { + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(file_name, strlen(file_name), cs); + table->field[3]->store((longlong) ((key_info->flags & + HA_NOSAME) ? 0 :1)); + table->field[4]->store(base_name, strlen(base_name), cs); + table->field[5]->store(key_info->name, strlen(key_info->name), cs); + table->field[6]->store((longlong) (j+1)); + str=(key_part->field ? key_part->field->field_name : + "?unknown field?"); + table->field[7]->store(str, strlen(str), cs); + if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER) + { + table->field[8]->store(((key_part->key_part_flag & + HA_REVERSE_SORT) ? + "D" : "A"), 1, cs); + table->field[8]->set_notnull(); + } + KEY *key=show_table->key_info+i; + if (key->rec_per_key[j]) + { + ha_rows records=(show_table->file->records / + key->rec_per_key[j]); + table->field[9]->store((longlong) records); + table->field[9]->set_notnull(); + } + if (!(key_info->flags & HA_FULLTEXT) && + (!key_part->field || + key_part->length != + show_table->field[key_part->fieldnr-1]->key_length())) + { + table->field[10]->store((longlong) key_part->length); + table->field[10]->set_notnull(); + } + uint flags= key_part->field ? key_part->field->flags : 0; + const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); + table->field[12]->store(pos, strlen(pos), cs); + pos= show_table->file->index_type(i); + table->field[13]->store(pos, strlen(pos), cs); + if (!show_table->keys_in_use.is_set(i)) + table->field[14]->store("disabled", 8, cs); + else + table->field[14]->store("", 0, cs); + table->field[14]->set_notnull(); + table->file->write_row(table->record[0]); + } + } + } + DBUG_RETURN(0); +} + + +int get_schema_views_record(THD *thd, struct st_table_list *tables, + TABLE *table, int res, + const char *base_name, const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_views_record"); + if (!res) + { + if (tables->view) + { + restore_record(table, default_values); + table->field[1]->store(tables->view_db.str, tables->view_db.length, cs); + table->field[2]->store(tables->view_name.str,tables->view_name.length,cs); + table->field[3]->store(tables->query.str, tables->query.length, cs); + table->field[4]->store("NONE", 4, cs); + if (tables->updatable_view) + table->field[5]->store("YES", 3, cs); + else + table->field[5]->store("NO", 2, cs); + table->file->write_row(table->record[0]); + } + } + DBUG_RETURN(0); +} + + +int get_schema_constarints_record(THD *thd, struct st_table_list *tables, + TABLE *table, int res, + const char *base_name, const char *file_name) +{ + CHARSET_INFO *cs= system_charset_info; + DBUG_ENTER("get_schema_constarints_record"); + if (!res) + { + List f_key_list; + TABLE *show_table= tables->table; + KEY *key_info=show_table->key_info; + uint primary_key= show_table->primary_key; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + for (uint i=0 ; i < show_table->keys ; i++, key_info++) + { + if (i != primary_key && !(key_info->flags & HA_NOSAME)) + continue; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(key_info->name, strlen(key_info->name), cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + if (i == primary_key && !strcmp(key_info->name, primary_key_name)) + table->field[5]->store("PRIMARY", 7, cs); + else if (key_info->flags & HA_NOSAME) + table->field[5]->store("UNIQUE", 6, cs); + table->file->write_row(table->record[0]); + } + + show_table->file->get_foreign_key_list(thd, &f_key_list); + FOREIGN_KEY_INFO *f_key_info; + List_iterator_fast it(f_key_list); + while ((f_key_info=it++)) + { + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(f_key_info->forein_id->str, + f_key_info->forein_id->length, cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + table->field[5]->store("FOREIGN", 7, system_charset_info); + table->field[6]->store(f_key_info->constraint_method->str, + f_key_info->constraint_method->length, cs); + table->field[6]->set_notnull(); + table->file->write_row(table->record[0]); + } + } + DBUG_RETURN(0); +} + + +int get_schema_key_column_usage_record(THD *thd, struct st_table_list *tables, + TABLE *table, int res, + const char *base_name, + const char *file_name) +{ + DBUG_ENTER("get_schema_key_column_usage_record"); + CHARSET_INFO *cs= system_charset_info; + if (!res) + { + List f_key_list; + TABLE *show_table= tables->table; + KEY *key_info=show_table->key_info; + uint primary_key= show_table->primary_key; + show_table->file->info(HA_STATUS_VARIABLE | + HA_STATUS_NO_LOCK | + HA_STATUS_TIME); + for (uint i=0 ; i < show_table->keys ; i++, key_info++) + { + if (i != primary_key && !(key_info->flags & HA_NOSAME)) + continue; + uint f_idx= 0; + KEY_PART_INFO *key_part= key_info->key_part; + for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) + { + uint f_idx= 0; + if (key_part->field) + { + f_idx++; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(key_info->name, strlen(key_info->name), cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + table->field[5]->store(key_part->field->field_name, + strlen(key_part->field->field_name), cs); + table->field[6]->store((longlong) f_idx); + table->file->write_row(table->record[0]); + } + } + } + + show_table->file->get_foreign_key_list(thd, &f_key_list); + FOREIGN_KEY_INFO *f_key_info; + List_iterator_fast it(f_key_list); + while ((f_key_info= it++)) + { + LEX_STRING *f_info, *r_info; + List_iterator_fast it(f_key_info->foreign_fields), + it1(f_key_info->referenced_fields); + uint f_idx= 0; + while ((f_info= it++)) + { + r_info= it1++; + f_idx++; + restore_record(table, default_values); + table->field[1]->store(base_name, strlen(base_name), cs); + table->field[2]->store(f_key_info->forein_id->str, + f_key_info->forein_id->length, cs); + table->field[3]->store(base_name, strlen(base_name), cs); + table->field[4]->store(file_name, strlen(file_name), cs); + table->field[5]->store(f_info->str, f_info->length, cs); + table->field[6]->store((longlong) f_idx); + table->field[7]->store(f_key_info->referenced_db->str, + f_key_info->referenced_db->length, cs); + table->field[7]->set_notnull(); + table->field[8]->store(f_key_info->referenced_table->str, + f_key_info->referenced_table->length, cs); + table->field[8]->set_notnull(); + table->field[9]->store(r_info->str, r_info->length, cs); + table->field[9]->set_notnull(); + table->file->write_row(table->record[0]); + } + } + } + DBUG_RETURN(0); +} + + +/* + Find schema_tables elment by name + + SYNOPSIS + find_schema_table() + thd thread handler + table_name table name + + RETURN + 0 table not found + # pointer to 'shema_tables' element +*/ + +ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name) +{ + ST_SCHEMA_TABLE *schema_table= schema_tables; + for ( ; schema_table->table_name; schema_table++) + { + if (!my_strcasecmp(system_charset_info, + schema_table->table_name, + table_name)) + return schema_table; + } + return 0; +} + + +ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx) +{ + return &schema_tables[schema_table_idx]; +} + + +/* + Create information_schema table using schema_table data + + SYNOPSIS + create_schema_table() + thd thread handler + schema_table pointer to 'shema_tables' element + + RETURN + # Pointer to created table + 0 Can't create table +*/ + +TABLE *create_schema_table(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + int field_count= 0; + Item *item; + TABLE *table; + List field_list; + ST_FIELD_INFO *fields_info= schema_table->fields_info; + DBUG_ENTER("create_schema_table"); + + for ( ; fields_info->field_name; fields_info++) + { + switch (fields_info->field_type) { + case MYSQL_TYPE_LONG: + if (!(item= new Item_int(fields_info->field_name, + fields_info->value, + fields_info->field_length))) + { + DBUG_RETURN(0); + } + break; + case MYSQL_TYPE_TIMESTAMP: + if (!(item=new Item_datetime(fields_info->field_name))) + { + DBUG_RETURN(0); + } + break; + default: + CHARSET_INFO *cs= system_charset_info; + if (fields_info->utf8) + cs= thd->charset(); + if (!(item= new Item_string("", fields_info->field_length, cs))) + { + DBUG_RETURN(0); + } + item->set_name(fields_info->field_name, + strlen(fields_info->field_name), cs); + break; + } + field_list.push_back(item); + item->maybe_null= fields_info->maybe_null; + field_count++; + } + TMP_TABLE_PARAM *tmp_table_param = + (TMP_TABLE_PARAM*) (thd->calloc(sizeof(TMP_TABLE_PARAM))); + tmp_table_param->init(); + tmp_table_param->field_count= field_count; + SELECT_LEX *select_lex= thd->lex->current_select; + if (!(table= create_tmp_table(thd, tmp_table_param, + field_list, (ORDER*) 0, 0, 0, + (select_lex->options | thd->options | + TMP_TABLE_ALL_COLUMNS), + HA_POS_ERROR, + (char *) schema_table->table_name))) + DBUG_RETURN(0); + DBUG_RETURN(table); +} + + +/* + For old SHOW compatibility. It is used when + old SHOW doesn't have generated column names + Make list of fields for SHOW + + SYNOPSIS + make_old_format() + thd thread handler + schema_table pointer to 'schema_tables' element + + RETURN + -1 errror + 0 success +*/ + +int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + ST_FIELD_INFO *field_info= schema_table->fields_info; + for ( ; field_info->field_name; field_info++) + { + if (field_info->old_name) + { + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (field) + { + field->set_name(field_info->old_name, + strlen(field_info->old_name), + system_charset_info); + if (add_item_to_list(thd, field)) + return 1; + } + } + } + return 0; +} + + +int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + char tmp[128]; + LEX *lex= thd->lex; + SELECT_LEX *sel= lex->current_select; + + if (!sel->item_list.elements) + { + ST_FIELD_INFO *field_info= &schema_table->fields_info[1]; + String buffer(tmp,sizeof(tmp), system_charset_info); + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (!field || add_item_to_list(thd, field)) + return 1; + buffer.length(0); + buffer.append(field_info->old_name); + if (lex->wild && lex->wild->ptr()) + { + buffer.append(" ("); + buffer.append(lex->wild->ptr()); + buffer.append(")"); + } + field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + } + return 0; +} + + +int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + char tmp[128]; + String buffer(tmp,sizeof(tmp), thd->charset()); + LEX *lex= thd->lex; + + ST_FIELD_INFO *field_info= &schema_table->fields_info[2]; + buffer.length(0); + buffer.append(field_info->old_name); + buffer.append(lex->select_lex.db); + if (lex->wild && lex->wild->ptr()) + { + buffer.append(" ("); + buffer.append(lex->wild->ptr()); + buffer.append(")"); + } + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (add_item_to_list(thd, field)) + return 1; + field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + if (thd->lex->verbose) + { + field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field_info= &schema_table->fields_info[3]; + field= new Item_field(NullS, NullS, field_info->field_name); + if (add_item_to_list(thd, field)) + return 1; + field->set_name(field_info->old_name, strlen(field_info->old_name), + system_charset_info); + } + return 0; +} + + +int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table) +{ + ST_FIELD_INFO *field_info= &schema_table->fields_info[3]; + int count= 2; + for ( ; field_info->field_name; field_info++) + { + count++; + if (field_info->old_name) + { + if (!thd->lex->verbose && (count == 12 ||count == 17 || count == 18)) + continue; + Item_field *field= new Item_field(NullS, NullS, field_info->field_name); + if (field) + { + field->set_name(field_info->old_name, + strlen(field_info->old_name), + system_charset_info); + if (add_item_to_list(thd, field)) + return 1; + } + } + } + return 0; +} + + +/* + Create information_schema table + + SYNOPSIS + mysql_schema_table() + thd thread handler + lex pointer to LEX + table_list pointer to table_list + + RETURN + 0 success + 1 error +*/ + +int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list) +{ + TABLE *table; + DBUG_ENTER("mysql_schema_table"); + if (!(table= table_list->schema_table-> + create_table(thd, table_list->schema_table))) + { + DBUG_RETURN(1); + } + table->tmp_table= TMP_TABLE; + table->grant.privilege= SELECT_ACL; + table_list->real_name= table->real_name; + table_list->table= table; + table->next= thd->derived_tables; + thd->derived_tables= table; + table_list->select_lex->options |= OPTION_SCHEMA_TABLE; + DBUG_RETURN(0); +} + + +/* + Generate select from information_schema table + + SYNOPSIS + make_schema_select() + thd thread handler + sel pointer to SELECT_LEX + schema_table_idx index of 'schema_tables' element + + RETURN + 0 success + 1 error +*/ + +int make_schema_select(THD *thd, SELECT_LEX *sel, + enum enum_schema_tables schema_table_idx) +{ + ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx); + LEX_STRING db, table; + DBUG_ENTER("mysql_schema_select"); + /* + We have to make non const db_name & table_name + because of lower_case_table_names + */ + make_lex_string(thd, &db, information_schema_name.str, + information_schema_name.length, 0); + make_lex_string(thd, &table, schema_table->table_name, + strlen(schema_table->table_name), 0); + if (!sel->item_list.elements && /* Handle old syntax */ + schema_table->old_format(thd, schema_table) || + !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0), + 0, 0, TL_READ, (List *) 0, + (List *) 0)) + { + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} + + +/* + Fill temporaty schema tables before SELECT + + SYNOPSIS + get_schema_tables_result() + join join which use schema tables + + RETURN + 0 success + 1 error +*/ + +int get_schema_tables_result(JOIN *join) +{ + DBUG_ENTER("get_schema_tables_result"); + JOIN_TAB *tmp_join_tab= join->join_tab+join->tables; + THD *thd= join->thd; + for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++) + { + if (!tab->table || !tab->table->pos_in_table_list) + break; + TABLE_LIST *table_list= tab->table->pos_in_table_list; + if (table_list->schema_table && !thd->only_prepare()) + { + TABLE *old_derived_tables= thd->derived_tables; + thd->derived_tables= 0; + thd->lex->sql_command= SQLCOM_SHOW_FIELDS; + table_list->table->file->records= 0; + MYSQL_LOCK *sql_lock= thd->lock; + thd->lock=0; + if (table_list->schema_table->fill_table(thd, table_list, + tab->select_cond)) + { + thd->derived_tables= old_derived_tables; + thd->lock= sql_lock; + DBUG_RETURN(-1); + } + thd->lock= sql_lock; + thd->lex->sql_command= SQLCOM_SELECT; + thd->derived_tables= old_derived_tables; + } + } + DBUG_RETURN(0); +} + + +ST_FIELD_INFO schema_fields_info[]= +{ + {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"SCHEMA_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Database"}, + {"DEFAULT_CHARACTER_SET_NAME", 60, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO tables_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Name"}, + {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, "Engine"}, + {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Version"}, + {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, 1, "Row_format"}, + {"ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Rows"}, + {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Avg_row_length"}, + {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Data_length"}, + {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Max_data_length"}, + {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Index_length"}, + {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Data_free"}, + {"AUTO_INCREMENT", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Auto_increment"}, + {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, "Create_time"}, + {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, "Update_time"}, + {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0, "Check_time"}, + {"COLLATION", 60, MYSQL_TYPE_STRING, 0, 1, 1, "Collation"}, + {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, 0, "Checksum"}, + {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, 1, "Create_options"}, + {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO columns_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Field"}, + {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"DATA_TYPE", 40, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"CHARACTER_SET_NAME", 40, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TYPE", 40, MYSQL_TYPE_STRING, 0, 0, 1, "Type"}, + {"COLLATION_NAME", 40, MYSQL_TYPE_STRING, 0, 1, 1, "Collation"}, + {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, "Null"}, + {"KEY", 3, MYSQL_TYPE_STRING, 0, 0, 1, "Key"}, + {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, "Default"}, + {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, 1, "Extra"}, + {"PRIVILIGES", 80, MYSQL_TYPE_STRING, 0, 0, 1, "Privileges"}, + {"COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO charsets_fields_info[]= +{ + {"CHARACTER_SET_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, "Charset"}, + {"Description", 60, MYSQL_TYPE_STRING, 0, 0, 1, "Description"}, + {"DEFAULT_COLLATE_NAME", 60, MYSQL_TYPE_STRING, 0, 0, 1, "Default collation"}, + {"Maxlen", 3 ,MYSQL_TYPE_LONG, 0, 0, 0, "Maxlen"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO collation_fields_info[]= +{ + {"COLLATION_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, "Collation"}, + {"Charset", 30, MYSQL_TYPE_STRING, 0, 0, 1, "Charset"}, + {"Id", 11, MYSQL_TYPE_LONG, 0, 0, 0, "Id"}, + {"Default", 30 ,MYSQL_TYPE_STRING, 0, 0, 1, "Default"}, + {"Compiled", 30 ,MYSQL_TYPE_STRING, 0, 0, 1, "Compiled"}, + {"Sortlen", 3 ,MYSQL_TYPE_LONG, 0, 0, 0, "Sortlen"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO coll_charset_app_fields_info[]= +{ + {"COLLATION_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CHARACTER_SET_NAME", 30, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO proc_fields_info[]= +{ + {"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"ROUTINE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Db"}, + {"ROUTINE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Name"}, + {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, 1, "Type"}, + {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 1, "Definer"}, + {"DTD_IDENTIFIER", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_BODY", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PARAMETER_STYLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"SQL_DATA_ACCESS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"SQL_PATH", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0, "Modified"}, + {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 1, "Created"}, + {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 1, "Security_type"}, + {"SQL_MODE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO stat_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Table"}, + {"NON_UNIQUE", 1, MYSQL_TYPE_LONG, 0, 0, 0, "Non_unique"}, + {"INDEX_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Key_name"}, + {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONG, 0, 0, 0, "Seq_in_index"}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Column_name"}, + {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, 1, "Collation"}, + {"CARDINALITY", 21, MYSQL_TYPE_LONG, 0, 1, 0, "Cardinality"}, + {"SUB_PART", 3, MYSQL_TYPE_LONG, 0, 1, 0, "Sub_part"}, + {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, 1, "Packed"}, + {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, "Null"}, + {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, 1, "Index_type"}, + {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, 1, "Comment"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO view_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CHECK_OPTION", 4, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO user_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO schema_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO table_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO column_privileges_fields_info[]= +{ + {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"PRIVILEGE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO table_constraints_fields_info[]= +{ + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_METHOD", 20, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO key_column_usage_fields_info[]= +{ + {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONG, 0, 0, 0, 0}, + {"REFERENCED_TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"REFERENCED_TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"REFERENCED_COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +ST_FIELD_INFO table_names_fields_info[]= +{ + {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 1, 0}, + {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Tables_in_"}, + {"TABLE_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, "Table_type"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} +}; + + +/* + Description of ST_FIELD_INFO in table.h +*/ + +ST_SCHEMA_TABLE schema_tables[]= +{ + {"SCHEMATA", schema_fields_info, create_schema_table, + fill_schema_shemata, make_schemata_old_format, 0, 1, -1}, + {"TABLES", tables_fields_info, create_schema_table, + get_all_tables, make_old_format, get_schema_tables_record, 1, 2}, + {"COLUMNS", columns_fields_info, create_schema_table, + get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2}, + {"CHARACTER_SETS", charsets_fields_info, create_schema_table, + fill_schema_charsets, make_old_format, 0, -1, -1}, + {"COLLATIONS", collation_fields_info, create_schema_table, + fill_schema_collation, make_old_format, 0, -1, -1}, + {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info, + create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1}, + {"ROUTINES", proc_fields_info, create_schema_table, + fill_schema_proc, make_old_format, 0, -1, -1}, + {"STATISTICS", stat_fields_info, create_schema_table, + get_all_tables, make_old_format, get_schema_stat_record, 1, 2}, + {"VIEWS", view_fields_info, create_schema_table, + get_all_tables, 0, get_schema_views_record, 1, 2}, + {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, + fill_schema_user_privileges, 0, 0, -1, -1}, + {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table, + fill_schema_schema_privileges, 0, 0, -1, -1}, + {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table, + fill_schema_table_privileges, 0, 0, -1, -1}, + {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table, + fill_schema_column_privileges, 0, 0, -1, -1}, + {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table, + get_all_tables, 0, get_schema_constarints_record, 3, 4}, + {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, + get_all_tables, 0, get_schema_key_column_usage_record, 3, 4}, + {"TABLE_NAMES", table_names_fields_info, create_schema_table, + get_all_tables, make_table_names_old_format, 0, 1, 2}, + {0, 0, 0, 0, 0, 0, 0, 0} +}; + + #ifdef __GNUC__ template class List_iterator_fast; template class List; diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 760ada9cdbd..941f08094b5 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -188,7 +188,8 @@ int mysql_create_view(THD *thd, for (tbl= tables; tbl; tbl= tbl->next_global) { /* is this table temporary and is not view? */ - if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view) + if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view && + !tbl->schema_table) { my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias); res= -1; @@ -494,7 +495,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, tbl; tbl= tbl->next_local) { - if (tbl->view && !tbl->updatable_view) + if ((tbl->view && !tbl->updatable_view) || tbl->schema_table) { view->updatable_view= 0; break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fe5ce7640ea..2f6cb53fc04 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -663,7 +663,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_table_alias %type - table_ident table_ident_nodb references + table_ident table_ident_nodb references from_table_ident %type remember_name remember_end opt_ident opt_db text_or_password @@ -5904,21 +5904,32 @@ show: SHOW ; show_param: - DATABASES wild - { Lex->sql_command= SQLCOM_SHOW_DATABASES; } - | opt_full TABLES opt_db wild - { - LEX *lex= Lex; - lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select_lex.db= $3; - } - | TABLE_SYM STATUS_SYM opt_db wild - { - LEX *lex= Lex; - lex->sql_command= SQLCOM_SHOW_TABLES; - lex->describe= DESCRIBE_EXTENDED; - lex->select_lex.db= $3; - } + DATABASES ext_select_item_list wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_DATABASES; + if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA)) + YYABORT; + } + | opt_full TABLES ext_select_item_list opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_TABLES; + lex->select_lex.db= $4; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES)) + YYABORT; + } + | TABLE_SYM STATUS_SYM ext_select_item_list opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATUS; + lex->select_lex.db= $4; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES)) + YYABORT; + } | OPEN_SYM TABLES opt_db wild { LEX *lex= Lex; @@ -5928,12 +5939,14 @@ show_param: | ENGINE_SYM storage_engines { Lex->create_info.db_type= $2; } show_engine_param - | opt_full COLUMNS from_or_in table_ident opt_db wild + | opt_full COLUMNS ext_select_item_list from_table_ident opt_db wild_and_where { - Lex->sql_command= SQLCOM_SHOW_FIELDS; + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_FIELDS; if ($5) $4->change_db($5); - if (!Select->add_table_to_list(YYTHD, $4, NULL, 0)) + if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS)) YYABORT; } | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ @@ -5959,13 +5972,15 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; } opt_limit_clause_init - | keys_or_index from_or_in table_ident opt_db - { - Lex->sql_command= SQLCOM_SHOW_KEYS; + | keys_or_index ext_select_item_list from_table_ident opt_db where_clause + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_KEYS; if ($4) $3->change_db($4); - if (!Select->add_table_to_list(YYTHD, $3, NULL, 0)) - YYABORT; + if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS)) + YYABORT; } | COLUMN_SYM TYPES_SYM { @@ -6012,10 +6027,22 @@ show_param: thd->lex->sql_command= SQLCOM_SHOW_VARIABLES; thd->lex->option_type= (enum_var_type) $1; } - | charset wild - { Lex->sql_command= SQLCOM_SHOW_CHARSETS; } - | COLLATION_SYM wild - { Lex->sql_command= SQLCOM_SHOW_COLLATIONS; } + | charset ext_select_item_list wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_CHARSETS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS)) + YYABORT; + } + | COLLATION_SYM ext_select_item_list wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_COLLATIONS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS)) + YYABORT; + } | BERKELEY_DB_SYM LOGS_SYM { Lex->sql_command= SQLCOM_SHOW_LOGS; WARN_DEPRECATED("SHOW BDB LOGS", "SHOW ENGINE BDB LOGS"); } | LOGS_SYM @@ -6094,13 +6121,21 @@ show_param: lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; lex->spname= $3; } - | PROCEDURE STATUS_SYM wild + | PROCEDURE STATUS_SYM ext_select_item_list wild_and_where { - Lex->sql_command = SQLCOM_SHOW_STATUS_PROC; + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_STATUS_PROC; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES)) + YYABORT; } - | FUNCTION_SYM STATUS_SYM wild + | FUNCTION_SYM STATUS_SYM ext_select_item_list wild_and_where { - Lex->sql_command = SQLCOM_SHOW_STATUS_FUNC; + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_STATUS_FUNC; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES)) + YYABORT; }; show_engine_param: @@ -6161,16 +6196,49 @@ binlog_from: /* empty */ { Lex->mi.pos = 4; /* skip magic number */ } | FROM ulonglong_num { Lex->mi.pos = $2; }; +from_table_ident: + /* empty */ { $$= 0; } + | from_or_in table_ident { $$= $2; } + ; + +wild_and_where: + /* empty */ + | LIKE TEXT_STRING_sys + { Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length, + system_charset_info); } + | WHERE expr + { + Select->where= $2; + if ($2) + $2->top_level_item(); + } + ; + +ext_select_item_list: + { + LEX *lex=Lex; + SELECT_LEX *sel= lex->current_select; + lex->lock_option= TL_READ; + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + } + /* empty */ + | select_item_list {}; + /* A Oracle compatible synonym for show */ describe: describe_command table_ident { - LEX *lex=Lex; - lex->wild=0; - lex->verbose=0; - lex->sql_command=SQLCOM_SHOW_FIELDS; - if (!Select->add_table_to_list(lex->thd, $2, NULL,0)) + LEX *lex= Lex; + lex->lock_option= TL_READ; + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + lex->sql_command= SQLCOM_SELECT; + lex->orig_sql_command= SQLCOM_SHOW_FIELDS; + lex->select_lex.db= 0; + lex->verbose= 0; + if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS)) YYABORT; } opt_describe_column {} diff --git a/sql/table.cc b/sql/table.cc index 0e8045abacf..68293335155 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1520,6 +1520,7 @@ void st_table_list::set_ancestor() if (ancestor->ancestor) ancestor->set_ancestor(); table= ancestor->table; + schema_table= ancestor->schema_table; ancestor->table->grant= grant; } diff --git a/sql/table.h b/sql/table.h index f95be1fcccb..86dd30dff68 100644 --- a/sql/table.h +++ b/sql/table.h @@ -204,6 +204,58 @@ struct st_table { }; +typedef struct st_foreign_key_info +{ + LEX_STRING *forein_id; + LEX_STRING *referenced_db; + LEX_STRING *referenced_table; + LEX_STRING *constraint_method; + List foreign_fields; + List referenced_fields; +} FOREIGN_KEY_INFO; + + +enum enum_schema_tables +{ + SCH_SCHEMATA= 0, SCH_TABLES, SCH_COLUMNS, SCH_CHARSETS, SCH_COLLATIONS, + SCH_COLLATION_CHARACTER_SET_APPLICABILITY, SCH_PROCEDURES, SCH_STATISTICS, + SCH_VIEWS, SCH_USER_PRIVILEGES, SCH_SCHEMA_PRIVILEGES, SCH_TABLE_PRIVILEGES, + SCH_COLUMN_PRIVILEGES, SCH_TABLE_CONSTRAINTS, SCH_KEY_COLUMN_USAGE, + SCH_TABLE_NAMES +}; + + +typedef struct st_field_info +{ + const char* field_name; + uint field_length; + enum enum_field_types field_type; + int value; + bool maybe_null; + bool utf8; + const char* old_name; +} ST_FIELD_INFO; + +struct st_table_list; +typedef class Item COND; + +typedef struct st_schema_table +{ + const char* table_name; + ST_FIELD_INFO *fields_info; + /* Create information_schema table */ + TABLE *(*create_table) (THD *thd, struct st_schema_table *schema_table); + /* Fill table with data */ + int (*fill_table) (THD *thd, struct st_table_list *tables, COND *cond); + /* Handle fileds for old SHOW */ + int (*old_format) (THD *thd, struct st_schema_table *schema_table); + int (*process_table) (THD *thd, struct st_table_list *tables, + TABLE *table, int res, const char *base_name, + const char *file_name); + int idx_field1, idx_field2; +} ST_SCHEMA_TABLE; + + #define JOIN_TYPE_LEFT 1 #define JOIN_TYPE_RIGHT 2 @@ -252,6 +304,8 @@ typedef struct st_table_list */ st_table_list *correspondent_table; st_select_lex_unit *derived; /* SELECT_LEX_UNIT of derived table */ + ST_SCHEMA_TABLE *schema_table; /* Information_schema table */ + st_select_lex *schema_select_lex; /* link to select_lex where this table was used */ st_select_lex *select_lex; st_lex *view; /* link on VIEW lex for merging */ -- cgit v1.2.1 From 8d71bcec217bead7d832d6ea4dca437c5f134577 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 13 Nov 2004 19:35:51 +0200 Subject: now my_printf_error is not better then my_error, but my_error call is shorter used only one implementation of format parser of (printf) fixed multistatement include/mysqld_error.h: newerror messages mysql-test/t/key.test: unknown error replaced with real error mysys/my_error.c: my_error & my_printf_error use my_vsprintf sql/field_conv.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/ha_innodb.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/handler.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/item.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/item_cmpfunc.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/item_func.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/item_strfunc.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/lock.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/log.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/parse_file.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/procedure.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/protocol.cc: no need reset thd->lex->found_colon to break multiline sequance now, send_error called too late sql/repl_failsafe.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/set_var.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/share/czech/errmsg.txt: new errors converted from unknown error sql/share/danish/errmsg.txt: new errors converted from unknown error sql/share/dutch/errmsg.txt: new errors converted from unknown error sql/share/english/errmsg.txt: new errors converted from unknown error sql/share/estonian/errmsg.txt: new errors converted from unknown error sql/share/french/errmsg.txt: new errors converted from unknown error sql/share/german/errmsg.txt: new errors converted from unknown error sql/share/greek/errmsg.txt: new errors converted from unknown error sql/share/hungarian/errmsg.txt: new errors converted from unknown error sql/share/italian/errmsg.txt: new errors converted from unknown error sql/share/japanese/errmsg.txt: new errors converted from unknown error sql/share/korean/errmsg.txt: new errors converted from unknown error sql/share/norwegian-ny/errmsg.txt: new errors converted from unknown error sql/share/norwegian/errmsg.txt: new errors converted from unknown error sql/share/polish/errmsg.txt: new errors converted from unknown error sql/share/portuguese/errmsg.txt: new errors converted from unknown error sql/share/romanian/errmsg.txt: new errors converted from unknown error sql/share/russian/errmsg.txt: new errors converted from unknown error sql/share/serbian/errmsg.txt: new errors converted from unknown error sql/share/slovak/errmsg.txt: new errors converted from unknown error sql/share/spanish/errmsg.txt: new errors converted from unknown error sql/share/swedish/errmsg.txt: new errors converted from unknown error sql/share/ukrainian/errmsg.txt: new errors converted from unknown error sql/slave.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sp.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sp_head.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_acl.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_analyse.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_base.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_class.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_db.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_delete.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_handler.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_insert.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_load.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_map.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_parse.cc: now my_printf_error is not better then my_error, but my_error call is shorter multi-row command fixed sql/sql_prepare.cc: now my_printf_error is not better then my_error, but my_error call is shorter remover send_error ingected from 4.1 sql/sql_rename.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_repl.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_select.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_show.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_table.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_trigger.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_udf.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_update.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_view.cc: now my_printf_error is not better then my_error, but my_error call is shorter sql/sql_yacc.yy: now my_printf_error is not better then my_error, but my_error call is shorter sql/table.cc: now my_printf_error is not better then my_error, but my_error call is shorter strings/my_vsnprintf.c: * format support added to my_vsprint --- sql/field_conv.cc | 6 +- sql/ha_innodb.cc | 9 +- sql/handler.cc | 19 ++-- sql/item.cc | 58 +++++------ sql/item_cmpfunc.cc | 11 +-- sql/item_func.cc | 49 ++++------ sql/item_strfunc.cc | 17 ++-- sql/lock.cc | 3 +- sql/log.cc | 3 +- sql/parse_file.cc | 38 +++----- sql/procedure.cc | 3 +- sql/protocol.cc | 1 - sql/repl_failsafe.cc | 22 ++--- sql/set_var.cc | 57 ++++------- 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/slave.cc | 8 +- sql/sp.cc | 16 ++- sql/sp_head.cc | 14 ++- sql/sql_acl.cc | 87 +++++++---------- sql/sql_analyse.cc | 15 +-- sql/sql_base.cc | 81 ++++++---------- sql/sql_class.cc | 10 +- sql/sql_db.cc | 29 +++--- sql/sql_delete.cc | 18 ++-- sql/sql_handler.cc | 30 +++--- sql/sql_insert.cc | 37 +++---- sql/sql_load.cc | 9 +- sql/sql_map.cc | 8 +- sql/sql_parse.cc | 198 +++++++++++++++----------------------- sql/sql_prepare.cc | 26 ++--- sql/sql_rename.cc | 6 +- sql/sql_repl.cc | 12 +-- sql/sql_select.cc | 13 +-- sql/sql_show.cc | 13 ++- sql/sql_table.cc | 144 ++++++++++----------------- sql/sql_trigger.cc | 7 +- sql/sql_udf.cc | 16 ++- sql/sql_update.cc | 44 ++++----- sql/sql_view.cc | 49 +++------- sql/sql_yacc.yy | 186 +++++++++++++---------------------- sql/table.cc | 22 ++--- 63 files changed, 576 insertions(+), 864 deletions(-) (limited to 'sql') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 61a5a28f47b..336408c5aa9 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -126,8 +126,7 @@ set_field_to_null(Field *field) return 0; } if (!current_thd->no_errors) - my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), - field->field_name); + my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); return -1; } @@ -185,8 +184,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) return 0; } if (!current_thd->no_errors) - my_printf_error(ER_BAD_NULL_ERROR,ER(ER_BAD_NULL_ERROR),MYF(0), - field->field_name); + my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); return -1; } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 34fc4873d43..88af43f8410 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -495,11 +495,10 @@ innobase_mysql_tmpfile(void) if (fd2 < 0) { DBUG_PRINT("error",("Got error %d on dup",fd2)); my_errno=errno; - my_printf_error(EE_OUT_OF_FILERESOURCES, - ER(EE_OUT_OF_FILERESOURCES), - MYF(ME_BELL+ME_WAITTANG), - filename, my_errno); - } + my_error(EE_OUT_OF_FILERESOURCES, + MYF(ME_BELL+ME_WAITTANG), + filename, my_errno); + } my_close(fd, MYF(MY_WME)); } return(fd2); diff --git a/sql/handler.cc b/sql/handler.cc index 8b6458d3662..e65fd6d097d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1200,8 +1200,7 @@ void handler::print_error(int error, myf errflag) str.length(max_length-4); str.append("..."); } - my_printf_error(ER_DUP_ENTRY, ER(ER_DUP_ENTRY), MYF(0), - str.c_ptr(), key_nr+1); + my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1); DBUG_VOID_RETURN; } textno=ER_DUP_KEY; @@ -1270,7 +1269,7 @@ void handler::print_error(int error, myf errflag) uint length=dirname_part(buff,table->path); buff[length-1]=0; db=buff+dirname_length(buff); - my_error(ER_NO_SUCH_TABLE,MYF(0),db,table->table_name); + my_error(ER_NO_SUCH_TABLE, MYF(0), db, table->table_name); break; } default: @@ -1284,20 +1283,16 @@ void handler::print_error(int error, myf errflag) { const char* engine= table_type(); if (temporary) - my_printf_error(ER_GET_TEMPORARY_ERRMSG, - ER(ER_GET_TEMPORARY_ERRMSG), MYF(0), - error, str.ptr(), engine); + my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine); else - my_printf_error(ER_GET_ERRMSG, - ER(ER_GET_ERRMSG), MYF(0), - error, str.ptr(), engine); + my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine); } else my_error(ER_GET_ERRNO,errflag,error); DBUG_VOID_RETURN; } } - my_error(textno,errflag,table->table_name,error); + my_error(textno, errflag, table->table_name, error); DBUG_VOID_RETURN; } @@ -1419,9 +1414,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, error=table.file->create(name,&table,create_info); VOID(closefrm(&table)); if (error) - my_printf_error(ER_CANT_CREATE_TABLE, ER(ER_CANT_CREATE_TABLE), - MYF(ME_BELL+ME_WAITTANG), - name,error); + my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name,error); DBUG_RETURN(error != 0); } diff --git a/sql/item.cc b/sql/item.cc index f37224c6bf5..42e1f23babd 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1621,8 +1621,8 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list) best match, they must reference the same column, otherwise the field is ambiguous. */ - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - MYF(0), find_item->full_name(), current_thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find_item->full_name(), current_thd->where); return NULL; } } @@ -1713,8 +1713,8 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select) DBUG_ASSERT(*select_ref); if (! (*select_ref)->fixed) { - my_error(ER_ILLEGAL_REFERENCE, MYF(0), ref->name, - "forward reference in item list"); + my_error(ER_ILLEGAL_REFERENCE, MYF(0), + ref->name, "forward reference in item list"); return NULL; } return (select->ref_pointer_array + counter); @@ -1895,8 +1895,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) if (upward_lookup) { // We can't say exactly what absent table or field - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - full_name(), thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where); } else { @@ -1988,14 +1987,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) db, tab, field_name) & VIEW_ANY_ACL))) { - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - "ANY", - thd->priv_user, - thd->host_or_ip, - field_name, - tab); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + "ANY", thd->priv_user, thd->host_or_ip, + field_name, tab); return TRUE; } } @@ -2455,8 +2449,7 @@ Item_real::Item_real(const char *str_arg, uint length) when we are in the parser */ DBUG_ASSERT(str_arg[length] == 0); - my_printf_error(ER_ILLEGAL_VALUE_FOR_TYPE, ER(ER_ILLEGAL_VALUE_FOR_TYPE), - MYF(0), "double", (char*) str_arg); + my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", (char*) str_arg); } presentation= name=(char*) str_arg; decimals=(uint8) nr_of_decimals(str_arg); @@ -2846,8 +2839,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) return TRUE; if (ref == not_found_item && from_field == not_found_field) { - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - this->full_name(), current_thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + this->full_name(), current_thd->where); ref= 0; // Safety return TRUE; } @@ -2889,8 +2882,8 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) else { /* The current reference cannot be resolved in this query. */ - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - this->full_name(), current_thd->where); + my_error(ER_BAD_FIELD_ERROR,MYF(0), + this->full_name(), current_thd->where); return TRUE; } } @@ -2907,11 +2900,10 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) current_sel->having_fix_field))) || !(*ref)->fixed) { - my_printf_error(ER_ILLEGAL_REFERENCE, ER(ER_ILLEGAL_REFERENCE), MYF(0), - name, - ((*ref)->with_sum_func? - "reference to group function": - "forward reference in item list")); + my_error(ER_ILLEGAL_REFERENCE, MYF(0), + name, ((*ref)->with_sum_func? + "reference to group function": + "forward reference in item list")); return TRUE; } max_length= (*ref)->max_length; @@ -2932,8 +2924,6 @@ void Item_ref::cleanup() DBUG_ENTER("Item_ref::cleanup"); Item_ident::cleanup(); result_field= 0; - if (hook_ptr) - *hook_ptr= orig_item; DBUG_VOID_RETURN; } @@ -3046,8 +3036,7 @@ bool Item_default_value::fix_fields(THD *thd, field_arg= (Item_field *)arg; if (field_arg->field->flags & NO_DEFAULT_VALUE_FLAG) { - my_printf_error(ER_NO_DEFAULT_FOR_FIELD, ER(ER_NO_DEFAULT_FOR_FIELD), - MYF(0), field_arg->field->field_name); + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name); return TRUE; } if (!(def_field= (Field*) sql_alloc(field_arg->field->size_of()))) @@ -3603,12 +3592,11 @@ bool Item_type_holder::join_types(THD *thd, Item *item) old_derivation= collation.derivation_name(); if (item_type == STRING_RESULT && collation.aggregate(item->collation)) { - my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, - ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), - old_cs, old_derivation, - item->collation.collation->name, - item->collation.derivation_name(), - "UNION"); + my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), + old_cs, old_derivation, + item->collation.collation->name, + item->collation.derivation_name(), + "UNION"); return 1; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 63d20b2dab3..4a4485ba2da 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -53,11 +53,10 @@ static void agg_cmp_type(Item_result *type, Item **items, uint nitems) static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, - ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), - c1.collation->name,c1.derivation_name(), - c2.collation->name,c2.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), + c1.collation->name,c1.derivation_name(), + c2.collation->name,c2.derivation_name(), + fname); } @@ -2437,7 +2436,7 @@ Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) cmp_collation.collation))) { (void) regerror(error,&preg,buff,sizeof(buff)); - my_printf_error(ER_REGEXP_ERROR,ER(ER_REGEXP_ERROR),MYF(0),buff); + my_error(ER_REGEXP_ERROR, MYF(0), buff); return TRUE; } regex_compiled=regex_is_const=1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 65e1cceb5bb..8d4ad54b511 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -45,11 +45,10 @@ bool check_reserved_words(LEX_STRING *name) static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, - ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), - c1.collation->name, c1.derivation_name(), - c2.collation->name, c2.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + fname); } static void my_coll_agg_error(DTCollation &c1, @@ -57,12 +56,11 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c3, const char *fname) { - my_printf_error(ER_CANT_AGGREGATE_3COLLATIONS, - ER(ER_CANT_AGGREGATE_3COLLATIONS), MYF(0), - c1.collation->name, c1.derivation_name(), - c2.collation->name, c2.derivation_name(), - c3.collation->name, c3.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_3COLLATIONS, MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + c3.collation->name, c3.derivation_name(), + fname); } @@ -76,8 +74,7 @@ static void my_coll_agg_error(Item** args, uint count, const char *fname) args[2]->collation, fname); else - my_printf_error(ER_CANT_AGGREGATE_NCOLLATIONS, - ER(ER_CANT_AGGREGATE_NCOLLATIONS), MYF(0),fname); + my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), fname); } @@ -1717,8 +1714,7 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, if (!tmp_udf) { - my_printf_error(ER_CANT_FIND_UDF,ER(ER_CANT_FIND_UDF),MYF(0),u_d->name.str, - errno); + my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str, errno); DBUG_RETURN(TRUE); } u_d=tmp_udf; @@ -1838,8 +1834,8 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, u_d->func_init; if ((error=(uchar) init(&initid, &f_args, thd->net.last_error))) { - my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), - u_d->name.str, thd->net.last_error); + my_error(ER_CANT_INITIALIZE_UDF, MYF(0), + u_d->name.str, thd->net.last_error); free_udf(u_d); DBUG_RETURN(TRUE); } @@ -1851,8 +1847,8 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func, initialized=1; if (error) { - my_printf_error(ER_CANT_INITIALIZE_UDF,ER(ER_CANT_INITIALIZE_UDF),MYF(0), - u_d->name.str, ER(ER_UNKNOWN_ERROR)); + my_error(ER_CANT_INITIALIZE_UDF, MYF(0), + u_d->name.str, ER(ER_UNKNOWN_ERROR)); DBUG_RETURN(TRUE); } DBUG_RETURN(FALSE); @@ -3378,8 +3374,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, { if (!var->is_struct()) { - my_printf_error(ER_VARIABLE_IS_NOT_STRUCT, ER(ER_VARIABLE_IS_NOT_STRUCT), - MYF(0), base_name->str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str); return 0; } } @@ -3544,8 +3539,7 @@ Item_func_sp::execute(Item **itp) m_sp= sp_find_function(thd, m_name); if (! m_sp) { - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(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); DBUG_RETURN(-1); } @@ -3579,8 +3573,7 @@ Item_func_sp::field_type() const DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); DBUG_RETURN(m_sp->m_returns); } - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(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); DBUG_RETURN(MYSQL_TYPE_STRING); } @@ -3596,8 +3589,7 @@ Item_func_sp::result_type() const { DBUG_RETURN(m_sp->result()); } - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(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); DBUG_RETURN(STRING_RESULT); } @@ -3610,8 +3602,7 @@ Item_func_sp::fix_length_and_dec() m_sp= sp_find_function(current_thd, m_name); if (! m_sp) { - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(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); } else { diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b3ba0b4a4f3..891cf48f7ca 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -42,11 +42,10 @@ String my_empty_string("",default_charset_info); static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) { - my_printf_error(ER_CANT_AGGREGATE_2COLLATIONS, - ER(ER_CANT_AGGREGATE_2COLLATIONS), MYF(0), - c1.collation->name, c1.derivation_name(), - c2.collation->name, c2.derivation_name(), - fname); + my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0), + c1.collation->name, c1.derivation_name(), + c2.collation->name, c2.derivation_name(), + fname); } uint nr_of_decimals(const char *str) @@ -2219,8 +2218,7 @@ void Item_func_set_collation::fix_length_and_dec() { if (!(set_collation= get_charset_by_name(colname,MYF(0)))) { - my_printf_error(ER_UNKNOWN_COLLATION, ER(ER_UNKNOWN_COLLATION), MYF(0), - colname); + my_error(ER_UNKNOWN_COLLATION, MYF(0), colname); return; } } @@ -2228,9 +2226,8 @@ void Item_func_set_collation::fix_length_and_dec() if (!set_collation || !my_charset_same(args[0]->collation.collation,set_collation)) { - my_printf_error(ER_COLLATION_CHARSET_MISMATCH, - ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), - colname, args[0]->collation.collation->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + colname, args[0]->collation.collation->csname); return; } collation.set(set_collation, DERIVATION_EXPLICIT); diff --git a/sql/lock.cc b/sql/lock.cc index 76b85946a4a..c4f1d681b76 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -430,8 +430,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, *write_lock_used=table; if (table->db_stat & HA_READ_ONLY) { - my_printf_error(ER_OPEN_AS_READONLY, ER(ER_OPEN_AS_READONLY), MYF(0), - table->table_name); + my_error(ER_OPEN_AS_READONLY, MYF(0), table->table_name); my_free((gptr) sql_lock,MYF(0)); return 0; } diff --git a/sql/log.cc b/sql/log.cc index 7f273247c6f..8f7e15d0db8 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1517,8 +1517,7 @@ err: if (my_errno == EFBIG) my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(0)); else - my_printf_error(ER_ERROR_ON_WRITE, ER(ER_ERROR_ON_WRITE), MYF(0), - name, errno); + my_error(ER_ERROR_ON_WRITE, MYF(0), name, errno); write_error=1; } if (file == &log_file) diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 91b29ce9b61..6c3a81384a6 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -350,8 +350,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, if (stat_info.st_size > INT_MAX-1) { - my_printf_error(ER_FPARSER_TOO_BIG_FILE, - ER(ER_FPARSER_TOO_BIG_FILE), MYF(0), file_name->str); + my_error(ER_FPARSER_TOO_BIG_FILE, MYF(0), file_name->str); DBUG_RETURN(0); } @@ -413,8 +412,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root, frm_error: if (bad_format_errors) { - my_printf_error(ER_FPARSER_BAD_HEADER, ER(ER_FPARSER_BAD_HEADER), MYF(0), - file_name->str); + my_error(ER_FPARSER_BAD_HEADER, MYF(0), file_name->str); DBUG_RETURN(0); } else @@ -627,8 +625,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, // it is comment if (!(ptr= strchr(ptr, '\n'))) { - my_printf_error(ER_FPARSER_EOF_IN_COMMENT, - ER(ER_FPARSER_EOF_IN_COMMENT), MYF(0), line); + my_error(ER_FPARSER_EOF_IN_COMMENT, MYF(0), line); DBUG_RETURN(TRUE); } ptr++; @@ -670,9 +667,8 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, (LEX_STRING *)(base + parameter->offset)))) { - my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, - ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), - parameter->name.str, line); + my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } break; @@ -683,9 +679,8 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, (LEX_STRING *) (base + parameter->offset)))) { - my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, - ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), - parameter->name.str, line); + my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } break; @@ -694,9 +689,8 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, case FILE_OPTIONS_REV: if (!(eol= strchr(ptr, '\n'))) { - my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, - ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), - parameter->name.str, line); + my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } { @@ -713,9 +707,8 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, /* yyyy-mm-dd HH:MM:SS = 19(PARSE_FILE_TIMESTAMPLENGTH) characters */ if (ptr[PARSE_FILE_TIMESTAMPLENGTH] != '\n') { - my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, - ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), - parameter->name.str, line); + my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), + parameter->name.str, line); DBUG_RETURN(TRUE); } memcpy(val->str, ptr, PARSE_FILE_TIMESTAMPLENGTH); @@ -754,9 +747,8 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, break; list_err_w_message: - my_printf_error(ER_FPARSER_ERROR_IN_PARAMETER, - ER(ER_FPARSER_ERROR_IN_PARAMETER), MYF(0), - parameter->name.str, line); + my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), + parameter->name.str, line); list_err: DBUG_RETURN(TRUE); } @@ -769,9 +761,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, // skip unknown parameter if (!(ptr= strchr(ptr, '\n'))) { - my_printf_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, - ER(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER), MYF(0), - line); + my_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, MYF(0), line); DBUG_RETURN(TRUE); } ptr++; diff --git a/sql/procedure.cc b/sql/procedure.cc index 7779f5ce085..420a4f6262b 100644 --- a/sql/procedure.cc +++ b/sql/procedure.cc @@ -65,8 +65,7 @@ setup_procedure(THD *thd,ORDER *param,select_result *result, DBUG_RETURN(proc); } } - my_printf_error(ER_UNKNOWN_PROCEDURE,ER(ER_UNKNOWN_PROCEDURE),MYF(0), - (*param->item)->name); + my_error(ER_UNKNOWN_PROCEDURE, MYF(0), (*param->item)->name); *error=1; DBUG_RETURN(0); } diff --git a/sql/protocol.cc b/sql/protocol.cc index e0d256fbe87..88be2710422 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -127,7 +127,6 @@ void net_send_error(THD *thd, uint sql_errno, const char *err) thd->net.report_error= 0; /* Abort multi-result sets */ - thd->lex->found_colon= 0; thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS; DBUG_VOID_RETURN; } diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index d49afb5f59d..5f67143065b 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -449,9 +449,8 @@ bool show_new_master(THD* thd) if (translate_master(thd, lex_mi, errmsg)) { if (errmsg[0]) - my_printf_error(ER_ERROR_WHEN_EXECUTING_COMMAND, - ER(ER_ERROR_WHEN_EXECUTING_COMMAND), MYF(0), - "SHOW NEW MASTER", errmsg); + my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), + "SHOW NEW MASTER", errmsg); DBUG_RETURN(TRUE); } else @@ -790,8 +789,7 @@ bool load_master_data(THD* thd) if (connect_to_master(thd, &mysql, active_mi)) { - my_printf_error(error= ER_CONNECT_TO_MASTER, - ER(ER_CONNECT_TO_MASTER), MYF(0), mysql_error(&mysql)); + my_error(error= ER_CONNECT_TO_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -803,8 +801,7 @@ bool load_master_data(THD* thd) if (mysql_real_query(&mysql, "SHOW DATABASES", 14) || !(db_res = mysql_store_result(&mysql))) { - my_printf_error(error = ER_QUERY_ON_MASTER, - ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -831,8 +828,7 @@ bool load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW MASTER STATUS",18) || !(master_status_res = mysql_store_result(&mysql))) { - my_printf_error(error = ER_QUERY_ON_MASTER, - ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } @@ -885,8 +881,7 @@ bool load_master_data(THD* thd) mysql_real_query(&mysql, "SHOW TABLES", 11) || !(*cur_table_res = mysql_store_result(&mysql))) { - my_printf_error(error = ER_QUERY_ON_MASTER, - ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); goto err; } @@ -943,8 +938,7 @@ bool load_master_data(THD* thd) if (mysql_real_query(&mysql, "UNLOCK TABLES", 13)) { - my_printf_error(error = ER_QUERY_ON_MASTER, - ER(ER_QUERY_ON_MASTER), MYF(0), mysql_error(&mysql)); + my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql)); goto err; } } @@ -953,7 +947,7 @@ bool load_master_data(THD* thd) 0 /* not only reset, but also reinit */, &errmsg)) { - my_printf_error(ER_RELAY_LOG_FAIL, ER(ER_RELAY_LOG_FAIL), MYF(0), errmsg); + my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); unlock_slave_threads(active_mi); pthread_mutex_unlock(&LOCK_active_mi); return TRUE; diff --git a/sql/set_var.cc b/sql/set_var.cc index a183f815a59..e5f3e17d17d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -899,8 +899,8 @@ bool sys_var_str::check(THD *thd, set_var *var) return 0; if ((res=(*check_func)(thd, var)) < 0) - my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), - name, var->value->str_value.ptr()); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), + name, var->value->str_value.ptr()); return res; } @@ -1174,8 +1174,7 @@ static int check_max_delayed_threads(THD *thd, set_var *var) val != (longlong) global_system_variables.max_insert_delayed_threads) { char buf[64]; - my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), - MYF(0), var->var->name, llstr(val, buf)); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf)); return 1; } return 0; @@ -1473,8 +1472,7 @@ bool sys_var::check_enum(THD *thd, set_var *var, TYPELIB *enum_names) return 0; err: - my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), - name, value); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value); return 1; } @@ -1515,8 +1513,7 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) return 0; err: - my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), - MYF(0), name, buff); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff); return 1; } @@ -1540,9 +1537,8 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) { if (var_type != OPT_DEFAULT) { - my_printf_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, - ER(ER_INCORRECT_GLOBAL_LOCAL_VAR), MYF(0), - name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); + my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), + name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL"); return 0; } /* As there was no local variable, return the global value */ @@ -1585,8 +1581,7 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base) return tmp; } default: - my_printf_error(ER_VAR_CANT_BE_READ, ER(ER_VAR_CANT_BE_READ), MYF(0), - name); + my_error(ER_VAR_CANT_BE_READ, MYF(0), name); } return 0; } @@ -1698,8 +1693,7 @@ bool sys_var_thd_date_time_format::check(THD *thd, set_var *var) if (!(format= date_time_format_make(date_time_type, res->ptr(), res->length()))) { - my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), - name, res->c_ptr()); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr()); return 1; } @@ -1797,14 +1791,12 @@ bool sys_var_collation::check(THD *thd, set_var *var) String str(buff,sizeof(buff), system_charset_info), *res; if (!(res=var->value->val_str(&str))) { - my_printf_error(ER_WRONG_VALUE_FOR_VAR, ER(ER_WRONG_VALUE_FOR_VAR), - MYF(0), name, "NULL"); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL"); return 1; } if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0)))) { - my_printf_error(ER_UNKNOWN_COLLATION, ER(ER_UNKNOWN_COLLATION), MYF(0), - res->c_ptr()); + my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr()); return 1; } } @@ -1814,8 +1806,7 @@ bool sys_var_collation::check(THD *thd, set_var *var) { char buf[20]; int10_to_str((int) var->value->val_int(), buf, -10); - my_printf_error(ER_UNKNOWN_COLLATION, ER(ER_UNKNOWN_COLLATION), MYF(0), - buf); + my_error(ER_UNKNOWN_COLLATION, MYF(0), buf); return 1; } } @@ -1836,8 +1827,7 @@ bool sys_var_character_set::check(THD *thd, set_var *var) { if (!nullable) { - my_printf_error(ER_WRONG_VALUE_FOR_VAR, - ER(ER_WRONG_VALUE_FOR_VAR), MYF(0), name, "NULL"); + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL"); return 1; } tmp= NULL; @@ -1845,8 +1835,7 @@ bool sys_var_character_set::check(THD *thd, set_var *var) else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) && !(tmp=get_old_charset_by_name(res->c_ptr()))) { - my_printf_error(ER_UNKNOWN_CHARACTER_SET, ER(ER_UNKNOWN_CHARACTER_SET), - MYF(0), res->c_ptr()); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); return 1; } } @@ -2443,8 +2432,7 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) if (!(var->save_result.time_zone= my_tz_find(res, thd->lex->time_zone_tables_used))) { - my_printf_error(ER_UNKNOWN_TIME_ZONE, ER(ER_UNKNOWN_TIME_ZONE), MYF(0), - res ? res->c_ptr() : "NULL"); + my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL"); return 1; } return 0; @@ -2726,8 +2714,7 @@ sys_var *find_sys_var(const char *str, uint length) length ? length : strlen(str)); if (!var) - my_printf_error(ER_UNKNOWN_SYSTEM_VARIABLE, ER(ER_UNKNOWN_SYSTEM_VARIABLE), - MYF(0), (char*) str); + my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str); return var; } @@ -2814,7 +2801,7 @@ int set_var::check(THD *thd) if (var->check_type(type)) { int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE; - my_printf_error(err, ER(err), MYF(0), var->name); + my_error(err, MYF(0), var->name); return -1; } if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))) @@ -2824,7 +2811,7 @@ int set_var::check(THD *thd) { if (var->check_default(type)) { - my_printf_error(ER_NO_DEFAULT, ER(ER_NO_DEFAULT), MYF(0), var->name); + my_error(ER_NO_DEFAULT, MYF(0), var->name); return -1; } return 0; @@ -2834,8 +2821,7 @@ int set_var::check(THD *thd) return -1; if (var->check_update_type(value->result_type())) { - my_printf_error(ER_WRONG_TYPE_FOR_VAR, ER(ER_WRONG_TYPE_FOR_VAR), MYF(0), - var->name); + my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name); return -1; } return var->check(thd, this) ? -1 : 0; @@ -2859,7 +2845,7 @@ int set_var::light_check(THD *thd) if (var->check_type(type)) { int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE; - my_printf_error(err, ER(err), MYF(0), var->name); + my_error(err, MYF(0), var->name); return -1; } if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)) @@ -2986,8 +2972,7 @@ bool sys_var_thd_storage_engine::check(THD *thd, set_var *var) value= "unknown"; err: - my_printf_error(ER_UNKNOWN_STORAGE_ENGINE, ER(ER_UNKNOWN_STORAGE_ENGINE), - MYF(0), value); + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value); return 1; } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 68816534d3a..c6ee78ffbb2 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -418,3 +418,5 @@ character-set=latin2 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index f475c9cd371..37b523526ce 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -409,3 +409,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 471997e8a22..7cf441e899d 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -418,3 +418,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 293227e64b9..990e3819053 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -406,3 +406,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 59e55207946..ff2f2a922ce 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -411,3 +411,5 @@ character-set=latin7 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index be6c440b509..2403eec4b60 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -406,3 +406,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 3afdd3ab496..757274bf1d5 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -419,3 +419,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index b0b158f5851..ce8fece95e7 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -406,3 +406,5 @@ character-set=greek "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index ba5f662a196..e93970e7eb8 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -411,3 +411,5 @@ character-set=latin2 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index d7ce95f8ed3..1745c31f114 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -406,3 +406,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 56df55f3db4..969bacc8d8f 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -410,3 +410,5 @@ character-set=ujis "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 1672dcb7dc6..cdb67ba004c 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -406,3 +406,5 @@ character-set=euckr "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 187bab28cf1..35b5a3d464b 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -408,3 +408,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index ba1d11aa158..bb34b3d653c 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -408,3 +408,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 9d9940ca69d..e4dfb9442dd 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -411,3 +411,5 @@ character-set=latin2 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 214b4753f1c..9b229613936 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -408,3 +408,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 2019bcc98f5..422143ea706 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -411,3 +411,5 @@ character-set=latin2 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 3354d6a7ee5..2da6cbdfc1a 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -411,3 +411,5 @@ character-set=koi8r "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 385f6f2044c..0abc324dfc8 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -399,3 +399,5 @@ character-set=cp1250 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 8ee06be1128..862ca741640 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -414,3 +414,5 @@ character-set=latin2 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 2215da6d57e..d3a4a029768 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -410,3 +410,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 92ef9e1659b..1b445e509c1 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -406,3 +406,5 @@ character-set=latin1 "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index c1f86886870..a7b139bc2c3 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -412,3 +412,5 @@ character-set=koi8u "Binary logging and replication forbid changing the global server %s" "Can't map file: %-.64s, errno: %d" "Wrong magic in %-.64s" +"Prepared statement contains too many placeholders" +"Key part '%-.64s' length cannot be 0" diff --git a/sql/slave.cc b/sql/slave.cc index d14e9784834..34785f1a18f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1502,7 +1502,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, err_msg= (char*) net->read_pos + ((mysql->server_capabilities & CLIENT_PROTOCOL_41) ? 3+SQLSTATE_LENGTH+1 : 3); - my_printf_error(ER_MASTER, ER(ER_MASTER), MYF(0), err_msg); + my_error(ER_MASTER, MYF(0), err_msg); DBUG_RETURN(1); } thd->command = COM_TABLE_DUMP; @@ -1580,8 +1580,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, error=file->repair(thd,&check_opt) != 0; thd->net.vio = save_vio; if (error) - my_printf_error(ER_INDEX_REBUILD, ER(ER_INDEX_REBUILD), MYF(0), - tables.table->real_name); + my_error(ER_INDEX_REBUILD, MYF(0), tables.table->real_name); err: close_thread_tables(thd); @@ -1608,8 +1607,7 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, } if (connect_to_master(thd, mysql, mi)) { - my_printf_error(ER_CONNECT_TO_MASTER, ER(ER_CONNECT_TO_MASTER), MYF(0), - mysql_error(mysql)); + my_error(ER_CONNECT_TO_MASTER, MYF(0), mysql_error(mysql)); mysql_close(mysql); DBUG_RETURN(1); } diff --git a/sql/sp.cc b/sql/sp.cc index bf1ad5d5fcf..5798eedbad9 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1001,8 +1001,7 @@ sp_cache_functions(THD *thd, LEX *lex) { delete newlex; thd->lex= oldlex; - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - "FUNCTION", ls->str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", ls->str); ret= 1; break; } @@ -1164,7 +1163,7 @@ sp_change_db(THD *thd, char *name, bool no_access_check) { if ((db_length > NAME_LEN) || check_db_name(dbname)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), dbname); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); x_free(dbname); DBUG_RETURN(1); } @@ -1183,11 +1182,10 @@ sp_change_db(THD *thd, char *name, bool no_access_check) if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - my_printf_error(ER_DBACCESS_DENIED_ERROR, ER(ER_DBACCESS_DENIED_ERROR), - MYF(0), - thd->priv_user, - thd->priv_host, - dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->priv_host, @@ -1203,7 +1201,7 @@ sp_change_db(THD *thd, char *name, bool no_access_check) path[length-1]=0; // remove ending '\' if (access(path,F_OK)) { - my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), dbname); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f07bb89e154..7db79128bb8 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -544,8 +544,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) { // Need to use my_printf_error here, or it will not terminate the // invoking query properly. - my_printf_error(ER_SP_WRONG_NO_OF_ARGS, ER(ER_SP_WRONG_NO_OF_ARGS), MYF(0), - "FUNCTION", m_name.str, params, argcount); + my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), + "FUNCTION", m_name.str, params, argcount); DBUG_RETURN(-1); } @@ -596,8 +596,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) *resp= it; else { - my_printf_error(ER_SP_NORETURNEND, ER(ER_SP_NORETURNEND), MYF(0), - m_name.str); + my_error(ER_SP_NORETURNEND, MYF(0), m_name.str); ret= -1; } } @@ -623,8 +622,8 @@ sp_head::execute_procedure(THD *thd, List *args) if (args->elements != params) { - my_printf_error(ER_SP_WRONG_NO_OF_ARGS, ER(ER_SP_WRONG_NO_OF_ARGS), MYF(0), - "PROCEDURE", m_name.str, params, args->elements); + my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0), "PROCEDURE", + m_name.str, params, args->elements); DBUG_RETURN(-1); } @@ -893,8 +892,7 @@ sp_head::check_backpatch(THD *thd) { if (bp->lab->type == SP_LAB_REF) { - my_printf_error(ER_SP_LILABEL_MISMATCH, ER(ER_SP_LILABEL_MISMATCH), - MYF(0), "GOTO", bp->lab->name); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "GOTO", bp->lab->name); return -1; } } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index cd20888cb98..1ad125beb0e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1534,9 +1534,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH && combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { - my_printf_error(ER_UNKNOWN_ERROR, - "Password hash should be a %d-digit hexadecimal number", - MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); + my_error(ER_PASSWD_LENGTH, MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); DBUG_RETURN(-1); } password_len= combo.password.length; @@ -1552,8 +1550,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, /* what == 'N' means revoke */ if (what == 'N') { - my_printf_error(ER_NONEXISTING_GRANT, ER(ER_NONEXISTING_GRAN), MYF(0), - combo.user.str, combo.host.str); + my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str); goto end; } /* @@ -1570,9 +1567,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, else if (((thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER) && !password_len) || !create_user) { - my_printf_error(ER_NO_PERMISSION_TO_CREATE_USER, - ER(ER_NO_PERMISSION_TO_CREATE_USER), MYF(0), - thd->user, thd->host_or_ip); + my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0), + thd->user, thd->host_or_ip); goto end; } old_row_exists = 0; @@ -1760,8 +1756,7 @@ static int replace_db_table(TABLE *table, const char *db, { if (what == 'N') { // no row, no revoke - my_printf_error(ER_NONEXISTING_GRANT, ER(ER_NONEXISTING_GRANT), MYF(0), - combo.user.str, combo.host.str); + my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str); goto abort; } old_row_exists = 0; @@ -2068,10 +2063,9 @@ static int replace_column_table(GRANT_TABLE *g_t, { if (revoke_grant) { - my_printf_error(ER_NONEXISTING_TABLE_GRANT, - ER(ER_NONEXISTING_TABLE_GRANT), MYF(0), - combo.user.str, combo.host.str, - table_name); /* purecov: inspected */ + my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), + combo.user.str, combo.host.str, + table_name); /* purecov: inspected */ result= -1; /* purecov: inspected */ continue; /* purecov: inspected */ } @@ -2237,10 +2231,9 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, */ if (revoke_grant) { // no row, no revoke - my_printf_error(ER_NONEXISTING_TABLE_GRANT, - ER(ER_NONEXISTING_TABLE_GRANT), MYF(0), - combo.user.str, combo.host.str, - table_name); /* purecov: deadcode */ + my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), + combo.user.str, combo.host.str, + table_name); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ } old_row_exists = 0; @@ -2369,8 +2362,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, column->column.length(), 0, 0, 0, 0, &unused_field_idx)) { - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - column->column.c_ptr(), table_list->alias); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + column->column.c_ptr(), table_list->alias); DBUG_RETURN(TRUE); } column_priv|= column->rights; @@ -2385,8 +2378,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, fn_format(buf,buf,"","",4+16+32); if (access(buf,F_OK)) { - my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), - table_list->db, table_list->alias); + my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias); DBUG_RETURN(TRUE); } } @@ -2474,9 +2466,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, { if (revoke_grant) { - my_printf_error(ER_NONEXISTING_TABLE_GRANT, - ER(ER_NONEXISTING_TABLE_GRANT), MYF(0), - Str->user.str, Str->host.str, table_list->real_name); + my_error(ER_NONEXISTING_TABLE_GRANT, MYF(0), + Str->user.str, Str->host.str, table_list->real_name); result= TRUE; continue; } @@ -2920,12 +2911,11 @@ err: command= "create view"; else if (want_access & SHOW_VIEW_ACL) command= "show create view"; - my_printf_error(ER_TABLEACCESS_DENIED_ERROR, - ER(ER_TABLEACCESS_DENIED_ERROR), MYF(0), - command, - thd->priv_user, - thd->host_or_ip, - table ? table->real_name : "unknown"); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + table ? table->real_name : "unknown"); } DBUG_RETURN(1); } @@ -2971,21 +2961,18 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant, } #endif - /* We must use my_printf_error() here! */ err: rw_unlock(&LOCK_grant); if (!show_tables) { char command[128]; get_privilege_desc(command, sizeof(command), want_access); - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - command, - thd->priv_user, - thd->host_or_ip, - name, - table_name); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + name, + table_name); } return 1; } @@ -3032,7 +3019,6 @@ bool check_grant_all_columns(THD *thd, ulong want_access, GRANT_INFO *grant, rw_unlock(&LOCK_grant); return 0; - /* We must use my_printf_error() here! */ err: rw_unlock(&LOCK_grant); err2: @@ -3041,14 +3027,12 @@ err2: command= "select"; else if (want_access & INSERT_ACL) command= "insert"; - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - command, - thd->priv_user, - thd->host_or_ip, - fields->name(), - table_name); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + command, + thd->priv_user, + thd->host_or_ip, + fields->name(), + table_name); return 1; } @@ -3232,9 +3216,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) } if (counter == acl_users.elements) { - my_printf_error(ER_NONEXISTING_GRANT, - ER(ER_NONEXISTING_GRANT), MYF(0), - lex_user->user.str, lex_user->host.str); + my_error(ER_NONEXISTING_GRANT, MYF(0), + lex_user->user.str, lex_user->host.str); DBUG_RETURN(TRUE); } diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 69b7b987152..2259d3bead8 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -81,18 +81,14 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val_real() < 0) { delete pc; - my_printf_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, - ER(ER_WRONG_PARAMETERS_TO_PROCEDURE), MYF(0), - proc_name); + my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); DBUG_RETURN(0); } pc->max_tree_elements = (uint) (*param->item)->val_int(); param = param->next; if (param->next) // no third parameter possible { - my_printf_error(ER_WRONG_PARAMCOUNT_TO_PROCEDURE, - ER(ER_WRONG_PARAMCOUNT_TO_PROCEDURE), MYF(0), - proc_name); + my_error(ER_WRONG_PARAMCOUNT_TO_PROCEDURE, MYF(0), proc_name); DBUG_RETURN(0); } // second parameter @@ -100,9 +96,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val_real() < 0) { delete pc; - my_printf_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, - ER(ER_WRONG_PARAMETERS_TO_PROCEDURE), MYF(0), - proc_name); + my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); DBUG_RETURN(0); } pc->max_treemem = (uint) (*param->item)->val_int(); @@ -111,8 +105,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, (*param->item)->val_real() < 0) { delete pc; - my_printf_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, - ER(ER_WRONG_PARAMETERS_TO_PROCEDURE), MYF(0), proc_name); + my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), proc_name); DBUG_RETURN(0); } // if only one parameter was given, it will be the value of max_tree_elements diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b32aa033209..5c9beb44e4c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -891,8 +891,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, { if (table->query_id == thd->query_id) { - my_printf_error(ER_CANT_REOPEN_TABLE, - ER(ER_CANT_REOPEN_TABLE), MYF(0), table->table_name); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->table_name); DBUG_RETURN(0); } table->query_id= thd->query_id; @@ -949,7 +948,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, VOID(pthread_mutex_unlock(&LOCK_open)); } } - my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias); + my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias); DBUG_RETURN(0); } @@ -1262,8 +1261,7 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh) next=table->next; if (!tables || (!db_stat && reopen_table(table,1))) { - my_printf_error(ER_CANT_REOPEN_TABLE, ER(ER_CANT_REOPEN_TABLE), - MYF(0),table->table_name); + my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->table_name); VOID(hash_delete(&open_cache,(byte*) table)); error=1; } @@ -1548,8 +1546,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, { /* Give right error message */ thd->clear_error(); - my_printf_error(ER_NOT_KEYFILE, ER(ER_NOT_KEYFILE), MYF(0), - name, my_errno); + my_error(ER_NOT_KEYFILE, MYF(0), name, my_errno); sql_print_error("Couldn't repair table: %s.%s",db,name); if (entry->file) closefrm(entry); @@ -1614,8 +1611,7 @@ err: { TABLE_LIST * view= table_desc->belong_to_view; thd->clear_error(); - my_printf_error(ER_VIEW_INVALID, ER(ER_VIEW_INVALID), MYF(0), - view->view_db.str, view->view_name.str); + my_error(ER_VIEW_INVALID, MYF(0), view->view_db.str, view->view_name.str); } DBUG_RETURN(1); } @@ -1743,9 +1739,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table, if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ && (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ) { - my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, - ER(ER_TABLE_NOT_LOCKED_FOR_WRITE), - MYF(0),table->table_name); + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->table_name); DBUG_RETURN(1); } if ((error=table->file->start_stmt(thd))) @@ -2330,8 +2324,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, { if (report_error == REPORT_ALL_ERRORS || report_error == IGNORE_EXCEPT_NON_UNIQUE) - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - item->full_name(),thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + item->full_name(),thd->where); return (Field*) 0; } found=find; @@ -2351,16 +2345,14 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, } if (report_error == REPORT_ALL_ERRORS || report_error == REPORT_EXCEPT_NON_UNIQUE) - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - table_name, thd->where); + my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where); else return (Field*) not_found_field; } else if (report_error == REPORT_ALL_ERRORS || report_error == REPORT_EXCEPT_NON_UNIQUE) - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - item->full_name(),thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(),thd->where); else return (Field*) not_found_field; return (Field*) 0; @@ -2373,8 +2365,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, { if (report_error == REPORT_ALL_ERRORS || report_error == REPORT_EXCEPT_NON_UNIQUE) - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - item->full_name(),thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(),thd->where); return (Field*) not_found_field; } @@ -2399,8 +2390,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, break; if (report_error == REPORT_ALL_ERRORS || report_error == IGNORE_EXCEPT_NON_UNIQUE) - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - name,thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where); return (Field*) 0; } found=field; @@ -2410,8 +2400,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, return found; if (report_error == REPORT_ALL_ERRORS || report_error == REPORT_EXCEPT_NON_UNIQUE) - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), - MYF(0), item->full_name(), thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where); else return (Field*) not_found_field; return (Field*) 0; @@ -2523,8 +2512,8 @@ find_item_in_list(Item *find, List &items, uint *counter, unaliased names only and will have duplicate error anyway. */ if (report_error != IGNORE_ERRORS) - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - MYF(0), find->full_name(), current_thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item**) 0; } found_unaliased= li.ref(); @@ -2548,8 +2537,8 @@ find_item_in_list(Item *find, List &items, uint *counter, if ((*found)->eq(item, 0)) continue; // Same field twice if (report_error != IGNORE_ERRORS) - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), - MYF(0), find->full_name(), current_thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item**) 0; } found= li.ref(); @@ -2592,8 +2581,8 @@ find_item_in_list(Item *find, List &items, uint *counter, if (found_unaliased_non_uniq) { if (report_error != IGNORE_ERRORS) - my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), MYF(0), - find->full_name(), current_thd->where); + my_error(ER_NON_UNIQ_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item **) 0; } if (found_unaliased) @@ -2608,8 +2597,8 @@ find_item_in_list(Item *find, List &items, uint *counter, if (report_error != REPORT_EXCEPT_NOT_FOUND) { if (report_error == REPORT_ALL_ERRORS) - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - find->full_name(), current_thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + find->full_name(), current_thd->where); return (Item **) 0; } else @@ -2822,9 +2811,8 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, (pos= find_type(&table->keynames, name->ptr(), name->length(), 1)) <= 0) { - my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, - ER(ER_KEY_COLUMN_DOES_NOT_EXITS), MYF(0), - name->c_ptr(), table->real_name); + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), + name->c_ptr(), table->real_name); map->set_all(); return 1; } @@ -2994,14 +2982,12 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, fld->field_name) & VIEW_ANY_ACL))) { - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - "ANY", - thd->priv_user, - thd->host_or_ip, - fld->field_name, - tab); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + "ANY", + thd->priv_user, + thd->host_or_ip, + fld->field_name, + tab); goto err; } } @@ -3042,8 +3028,7 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name, if (!table_name) my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0)); else - my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), - table_name); + my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name); err: DBUG_RETURN(1); @@ -3573,8 +3558,7 @@ open_new_frm(const char *path, const char *alias, { if (table_desc == 0 || table_desc->required_type == FRMTYPE_TABLE) { - my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), - db, table_name, "BASE TABLE"); + my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE"); goto err; } if (mysql_make_view(parser, table_desc)) @@ -3583,8 +3567,7 @@ open_new_frm(const char *path, const char *alias, else { /* only VIEWs are supported now */ - my_printf_error(ER_FRM_UNKNOWN_TYPE, ER(ER_FRM_UNKNOWN_TYPE), MYF(0), - path, parser->type()->str); + my_error(ER_FRM_UNKNOWN_TYPE, MYF(0), path, parser->type()->str); goto err; } DBUG_RETURN(0); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 6f236f42df9..e69c0f52c93 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -701,8 +701,8 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, long key_length) key_length + 1); if (!new_table) { - my_printf_error(EE_OUTOFMEMORY, ER(EE_OUTOFMEMORY), MYF(ME_BELL), - ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); + my_error(EE_OUTOFMEMORY, MYF(ME_BELL), + ALIGN_SIZE(sizeof(TABLE_LIST)) + key_length + 1); killed= KILL_CONNECTION; return 0; } @@ -1018,8 +1018,7 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, if (!access(path, F_OK)) { - my_printf_error(ER_FILE_EXISTS_ERROR, ER(ER_FILE_EXISTS_ERROR), MYF(0), - exchange->file_name); + my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); return -1; } /* Create the file world readable */ @@ -1263,8 +1262,7 @@ bool select_dump::send_data(List &items) } else if (my_b_write(&cache,(byte*) res->ptr(),res->length())) { - my_printf_error(ER_ERROR_ON_WRITE, ER(ER_ERROR_ON_WRITE), MYF(0), - path, my_errno); + my_error(ER_ERROR_ON_WRITE, MYF(0), path, my_errno); goto err; } } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 42d6549f843..ad4887146d8 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -408,8 +408,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, { if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) { - my_printf_error(ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), MYF(0), - db); + my_error(ER_DB_CREATE_EXISTS, MYF(0), db); error= -1; goto exit; } @@ -419,13 +418,12 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, { if (my_errno != ENOENT) { - my_printf_error(EE_STAT, ER(EE_STAT), MYF(0), path, my_errno); + my_error(EE_STAT, MYF(0), path, my_errno); goto exit; } if (my_mkdir(path,0777,MYF(0)) < 0) { - my_printf_error(ER_CANT_CREATE_DB, ER(ER_CANT_CREATE_DB), - MYF(0), db, my_errno); + my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno); error= -1; goto exit; } @@ -579,7 +577,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (!if_exists) { error= -1; - my_printf_error(ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), MYF(0), db); + my_error(ER_DB_DROP_EXISTS, MYF(0), db); goto exit; } else @@ -803,8 +801,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, */ if (found_other_files) { - my_printf_error(ER_DB_DROP_RMDIR, ER(ER_DB_DROP_RMDIR), MYF(0), - org_path, EEXIST); + my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST); DBUG_RETURN(-1); } else @@ -867,8 +864,7 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) *--pos=0; if (rmdir(path) < 0 && send_error) { - my_printf_error(ER_DB_DROP_RMDIR, ER(ER_DB_DROP_RMDIR), MYF(0), - path, errno); + my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno); DBUG_RETURN(-1); } DBUG_RETURN(0); @@ -995,7 +991,7 @@ bool mysql_change_db(THD *thd, const char *name) } if (check_db_name(dbname)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), dbname); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); x_free(dbname); DBUG_RETURN(1); } @@ -1008,11 +1004,10 @@ bool mysql_change_db(THD *thd, const char *name) thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - my_printf_error(ER_DBACCESS_DENIED_ERROR, - ER(ER_DBACCESS_DENIED_ERROR), MYF(0), - thd->priv_user, - thd->priv_host, - dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->priv_host, @@ -1027,7 +1022,7 @@ bool mysql_change_db(THD *thd, const char *name) path[length-1]=0; // remove ending '\' if (access(path,F_OK)) { - my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), dbname); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); my_free(dbname,MYF(0)); DBUG_RETURN(1); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 31363583806..a1ac6162b82 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -290,14 +290,12 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) DBUG_RETURN(TRUE); if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), MYF(0), - table_list->alias, "DELETE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "DELETE"); DBUG_RETURN(TRUE); } if (unique_table(table_list, table_list->next_global)) { - my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), MYF(0), - table_list->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, conds); @@ -354,8 +352,8 @@ bool mysql_multi_delete_prepare(THD *thd) if (!target_tbl->correspondent_table->updatable || check_key_in_view(thd, target_tbl->correspondent_table)) { - my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), - MYF(0), target_tbl->real_name, "DELETE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), + target_tbl->real_name, "DELETE"); DBUG_RETURN(TRUE); } /* @@ -372,8 +370,8 @@ bool mysql_multi_delete_prepare(THD *thd) un->check_updateable(target_tbl->correspondent_table->db, target_tbl->correspondent_table->real_name)) { - my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), - MYF(0), target_tbl->correspondent_table->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), + target_tbl->correspondent_table->real_name); DBUG_RETURN(TRUE); } } @@ -736,8 +734,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) db_type table_type; if ((table_type=get_table_type(path)) == DB_TYPE_UNKNOWN) { - my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), - table_list->db, table_list->real_name); + my_error(ER_NO_SUCH_TABLE, MYF(0), + table_list->db, table_list->real_name); DBUG_RETURN(TRUE); } if (!ha_supports_generate(table_type)) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index e1df25ae724..853b3dd37c6 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -173,8 +173,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) { DBUG_PRINT("info",("duplicate '%s'", tables->alias)); if (! reopen) - my_printf_error(ER_NONUNIQ_TABLE, ER(ER_NONUNIQ_TABLE), - MYF(0), tables->alias); + my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias); goto err; } } @@ -198,7 +197,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) if (! (tables->table->file->table_flags() & HA_CAN_SQL_HANDLER)) { if (! reopen) - my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->alias); + my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); mysql_ha_close(thd, tables); goto err; } @@ -257,11 +256,11 @@ err: will be closed. Broadcasts a COND_refresh condition. RETURN - 0 ok - != 0 error + FALSE ok + TRUE error */ -int mysql_ha_close(THD *thd, TABLE_LIST *tables) +bool mysql_ha_close(THD *thd, TABLE_LIST *tables) { TABLE_LIST *hash_tables; TABLE **table_ptr; @@ -299,15 +298,14 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables) } else { - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - tables->alias, "HANDLER"); + my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER"); DBUG_PRINT("exit",("ERROR")); - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } send_ok(thd); DBUG_PRINT("exit", ("OK")); - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } @@ -403,11 +401,9 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, strxnmov(buff, sizeof(buff), tables->db, ".", tables->real_name, NullS); else strncpy(buff, tables->alias, sizeof(buff)); - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - buff, "HANDLER"); + my_error(ER_UNKNOWN_TABLE, MYF(0), buff, "HANDLER"); #else - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - tables->alias, "HANDLER"); + my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER"); #endif goto err0; } @@ -422,8 +418,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, { if ((keyno=find_type(keyname, &table->keynames, 1+2)-1)<0) { - my_printf_error(ER_KEY_DOES_NOT_EXITS,ER(ER_KEY_DOES_NOT_EXITS),MYF(0), - keyname,tables->alias); + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); goto err0; } table->file->ha_index_or_rnd_end(); @@ -491,8 +486,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables, KEY_PART_INFO *key_part=keyinfo->key_part; if (key_expr->elements > keyinfo->key_parts) { - my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS), - MYF(0),keyinfo->key_parts); + my_error(ER_TOO_MANY_KEY_PARTS, MYF(0), keyinfo->key_parts); goto err; } List_iterator it_ke(*key_expr); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f39753f0e62..2fddaed5f45 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -58,9 +58,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, { if (values.elements != table->fields) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); return -1; } #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -82,9 +80,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, int res; if (fields.elements != values.elements) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); return -1; } @@ -100,8 +96,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, if (check_unique && thd->dupp_field) { - my_printf_error(ER_FIELD_SPECIFIED_TWICE, ER(ER_FIELD_SPECIFIED_TWICE), - MYF(0), thd->dupp_field->field_name); + my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name); return -1; } if (table->timestamp_field && // Don't set timestamp if used @@ -172,9 +167,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table_list->db ? table_list->db : thd->db, table_list->real_name)) { - my_printf_error(ER_DELAYED_INSERT_TABLE_LOCKED, - ER(ER_DELAYED_INSERT_TABLE_LOCKED), - MYF(0), table_list->real_name); + my_error(ER_DELAYED_INSERT_TABLE_LOCKED, MYF(0), + table_list->real_name); DBUG_RETURN(TRUE); } } @@ -228,9 +222,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, counter++; if (values->elements != value_count) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); goto abort; } if (setup_fields(thd, 0, table_list, *values, 0, 0, 0)) @@ -602,8 +594,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, (insert_into_view && check_view_insertability(table_list, thd->query_id))) { - my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), - MYF(0), table_list->alias, "INSERT"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "INSERT"); DBUG_RETURN(1); } DBUG_RETURN(0); @@ -650,8 +641,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, if (unique_table(table_list, table_list->next_global)) { - my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), - MYF(0), table_list->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); DBUG_RETURN(TRUE); } thd->lex->select_lex.first_execution= 0; @@ -831,9 +821,7 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry) if ((*field)->query_id != thd->query_id && ((*field)->flags & NO_DEFAULT_VALUE_FLAG)) { - my_printf_error(ER_NO_DEFAULT_FOR_FIELD, - ER(ER_NO_DEFAULT_FOR_FIELD),MYF(0), - (*field)->field_name); + my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), (*field)->field_name); return 1; } } @@ -1325,8 +1313,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) if (!(di->table->file->table_flags() & HA_CAN_INSERT_DELAYED)) { thd->fatal_error(); - my_printf_error(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0), - di->table_list.real_name); + my_error(ER_ILLEGAL_HA, MYF(0), di->table_list.real_name); goto end; } di->table->copy_blobs=1; @@ -1886,9 +1873,7 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) if (table->fields < values.elements) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0),1); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1); DBUG_RETURN(-1); } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 4f5cf463fb6..d9e4943f322 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -125,8 +125,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(-1); if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), - MYF(0), table_list->alias, "LOAD"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "LOAD"); DBUG_RETURN(TRUE); } table= table_list->table; @@ -149,8 +148,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(TRUE); if (thd->dupp_field) { - my_printf_error(ER_FIELD_SPECIFIED_TWICE, ER(ER_FIELD_SPECIFIED_TWICE), - MYF(0), thd->dupp_field->field_name); + my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dupp_field->field_name); DBUG_RETURN(TRUE); } if (check_that_all_fields_are_given_values(thd, table)) @@ -223,8 +221,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ((stat_info.st_mode & S_IFREG) == S_IFREG || (stat_info.st_mode & S_IFIFO) == S_IFIFO))) { - my_printf_error(ER_TEXTFILE_NOT_READABLE, - ER(ER_TEXTFILE_NOT_READABLE), MYF(0), name); + my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name); DBUG_RETURN(TRUE); } if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) diff --git a/sql/sql_map.cc b/sql/sql_map.cc index 917a8f2c30f..687e60b7c72 100644 --- a/sql/sql_map.cc +++ b/sql/sql_map.cc @@ -47,13 +47,12 @@ mapped_files::mapped_files(const my_string filename,byte *magic,uint magic_lengt 0L))) { error=errno; - my_printf_error(ER_NO_FILE_MAPPING, ER(ER_NO_FILE_MAPPING), MYF(0), - (my_string) name, error); + my_error(ER_NO_FILE_MAPPING, MYF(0), (my_string) name, error); } } if (map && memcmp(map,magic,magic_length)) { - my_printf_error(ER_WRONG_MAGIC, ER(ER_WRONG_MAGIC), MYF(0), name); + my_error(ER_WRONG_MAGIC, MYF(0), name); VOID(munmap(map,size)); map=0; } @@ -112,8 +111,7 @@ mapped_files *map_file(const my_string name,byte *magic,uint magic_length) { map->use_count++; if (!map->map) - my_printf_error(ER_NO_FILE_MAPPING, ER(ER_NO_FILE_MAPPING), MYF(0), - path, map->error); + my_error(ER_NO_FILE_MAPPING, MYF(0), path, map->error); } VOID(pthread_mutex_unlock(&LOCK_mapped_file)); return map; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 652a0493f6b..9d56ea27130 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1204,8 +1204,7 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) if (!db || check_db_name(db)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), - db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME ,MYF(0), db ? db : "NULL"); goto err; } if (lower_case_table_names) @@ -1502,7 +1501,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_PRINT("query",("%-.4096s",thd->query)); mysql_parse(thd,thd->query, thd->query_length); - while (!thd->killed && !thd->is_fatal_error && thd->lex->found_colon) + while (!thd->killed && thd->lex->found_colon && !thd->net.report_error) { char *packet= thd->lex->found_colon; /* @@ -1620,8 +1619,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, // null test to handle EOM if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), - db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); break; } if (check_access(thd,CREATE_ACL,db,0,1,0)) @@ -1630,7 +1628,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, bzero(&create_info, sizeof(create_info)); if (mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db), &create_info, 0) < 0) - send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); + error= TRUE; break; } case COM_DROP_DB: // QQ: To be removed @@ -1641,8 +1639,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* null test to handle EOM */ if (!db || !(alias= thd->strdup(db)) || check_db_name(db)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), - MYF(0), db ? db : "NULL"); + my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL"); break; } if (check_access(thd,DROP_ACL,db,0,1,0)) @@ -1656,7 +1653,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, mysql_log.write(thd,command,db); if (mysql_rm_db(thd, (lower_case_table_names == 2 ? alias : db), 0, 0) < 0) - send_error(thd, thd->killed ? ER_SERVER_SHUTDOWN : 0); + error= TRUE; break; } #ifndef EMBEDDED_LIBRARY @@ -2189,11 +2186,10 @@ mysql_execute_command(THD *thd) } else { - my_printf_error(ER_UNKNOWN_STMT_HANDLER, ER(ER_UNKNOWN_STMT_HANDLER), - MYF(0), - lex->prepared_stmt_name.length, - lex->prepared_stmt_name.str, - "DEALLOCATE PREPARE"); + my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), + lex->prepared_stmt_name.length, + lex->prepared_stmt_name.str, + "DEALLOCATE PREPARE"); goto error; } break; @@ -2386,8 +2382,7 @@ mysql_execute_command(THD *thd) } if (strlen(first_table->real_name) > NAME_LEN) { - my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), - first_table->real_name); + my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->real_name); break; } pthread_mutex_lock(&LOCK_active_mi); @@ -2455,8 +2450,7 @@ mysql_execute_command(THD *thd) if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && unique_table(create_table, select_tables)) { - my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), - MYF(0), create_table->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), create_table->real_name); goto create_error; } /* If we create merge table, we have to test tables in merge, too */ @@ -2469,8 +2463,7 @@ mysql_execute_command(THD *thd) { if (unique_table(tab, select_tables)) { - my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), - MYF(0), tab->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), tab->real_name); goto create_error; } } @@ -2579,8 +2572,7 @@ create_error: ulong priv=0; if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN)) { - my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), - lex->name); + my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name); goto error; } if (!select_lex->db) @@ -3054,18 +3046,17 @@ create_error: remove_escape(db); // Fix escaped '_' if (check_db_name(db)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), db); + my_error(ER_WRONG_DB_NAME, MYF(0), db); goto error; } if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) goto error; /* purecov: inspected */ if (!thd->col_access && check_grant_db(thd,db)) { - my_printf_error(ER_DBACCESS_DENIED_ERROR, - ER(ER_DBACCESS_DENIED_ERROR), MYF(0), - thd->priv_user, - thd->priv_host, - db); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + db); goto error; } /* grant is checked in mysqld_show_tables */ @@ -3231,8 +3222,7 @@ create_error: char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), - lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3262,8 +3252,7 @@ create_error: char *alias; if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), - lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3298,8 +3287,7 @@ create_error: { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), - lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } /* @@ -3333,8 +3321,7 @@ create_error: { if (!strip_sp(lex->name) || check_db_name(lex->name)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), - lex->name); + my_error(ER_WRONG_DB_NAME, MYF(0), lex->name); break; } if (check_access(thd,SELECT_ACL,lex->name,0,1,0)) @@ -3356,8 +3343,7 @@ create_error: #ifdef HAVE_DLOPEN if ((sph= sp_find_function(thd, lex->spname))) { - my_printf_error(ER_UDF_EXISTS, ER(ER_UDF_EXISTS), MYF(0), - lex->spname->m_name.str); + my_error(ER_UDF_EXISTS, MYF(0), lex->spname->m_name.str); goto error; } if (!(res = mysql_create_function(thd,&lex->udf))) @@ -3642,7 +3628,7 @@ create_error: if (udf) { - my_printf_error(ER_UDF_EXISTS, ER(ER_UDF_EXISTS), MYF(0), name); + my_error(ER_UDF_EXISTS, MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; @@ -3652,7 +3638,7 @@ create_error: if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && !lex->sphead->m_has_return) { - my_printf_error(ER_SP_NORETURN, ER(ER_SP_NORETURN), MYF(0), name); + my_error(ER_SP_NORETURN, MYF(0), name); delete lex->sphead; lex->sphead= 0; goto error; @@ -3667,22 +3653,19 @@ create_error: lex->sphead= 0; break; case SP_WRITE_ROW_FAILED: - my_printf_error(ER_SP_ALREADY_EXISTS, ER(ER_SP_ALREADY_EXISTS), MYF(0), - SP_TYPE_STRING(lex), name); + my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; case SP_NO_DB_ERROR: - my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), - lex->sphead->m_db.str); + my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; goto error; default: - my_printf_error(ER_SP_STORE_FAILED, ER(ER_SP_STORE_FAILED), MYF(0), - SP_TYPE_STRING(lex), name); + my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name); lex->unit.cleanup(); delete lex->sphead; lex->sphead= 0; @@ -3696,8 +3679,7 @@ create_error: if (!(sp= sp_find_procedure(thd, lex->spname))) { - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), - MYF(0), "PROCEDURE", + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE", lex->spname->m_qname.str); goto error; } @@ -3795,12 +3777,12 @@ create_error: send_ok(thd); break; case SP_KEY_NOT_FOUND: - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; default: - my_printf_error(ER_SP_CANT_ALTER, ER(ER_SP_CANT_ALTER), MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + my_error(ER_SP_CANT_ALTER, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; } break; @@ -3862,12 +3844,12 @@ create_error: send_ok(thd); break; } - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; default: - my_printf_error(ER_SP_DROP_FAILED, ER(ER_SP_DROP_FAILED), MYF(0), - SP_COM_STRING(lex), lex->spname->m_qname.str); + my_error(ER_SP_DROP_FAILED, MYF(0), + SP_COM_STRING(lex), lex->spname->m_qname.str); goto error; } break; @@ -3876,14 +3858,13 @@ create_error: { if (lex->spname->m_name.length > NAME_LEN) { - my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), - lex->spname->m_name.str); + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); goto error; } if (sp_show_create_procedure(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - SP_COM_STRING(lex), lex->spname->m_name.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } break; @@ -3892,14 +3873,13 @@ create_error: { if (lex->spname->m_name.length > NAME_LEN) { - my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), - lex->spname->m_name.str); + my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); goto error; } if (sp_show_create_function(thd, lex->spname) != SP_OK) { /* We don't distinguish between errors for now */ - my_printf_error(ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), MYF(0), - SP_COM_STRING(lex), lex->spname->m_name.str); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), + SP_COM_STRING(lex), lex->spname->m_name.str); goto error; } break; @@ -4103,13 +4083,12 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, { // We can never grant this DBUG_PRINT("error",("No possible access")); if (!no_errors) - my_printf_error(ER_ACCESS_DENIED_ERROR, - ER(ER_ACCESS_DENIED_ERROR), MYF(0), - thd->priv_user, - thd->priv_host, - (thd->password ? - ER(ER_YES) : - ER(ER_NO)));/* purecov: tested */ + my_error(ER_ACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + (thd->password ? + ER(ER_YES) : + ER(ER_NO))); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ } @@ -4136,13 +4115,12 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_PRINT("error",("Access denied")); if (!no_errors) - my_printf_error(ER_DBACCESS_DENIED_ERROR, - ER(ER_DBACCESS_DENIED_ERROR), MYF(0), - thd->priv_user, - thd->priv_host, - (db ? db : (thd->db ? - thd->db : - "unknown"))); /* purecov: tested */ + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, + thd->priv_host, + (db ? db : (thd->db ? + thd->db : + "unknown"))); /* purecov: tested */ DBUG_RETURN(TRUE); /* purecov: tested */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4176,8 +4154,7 @@ bool check_global_access(THD *thd, ulong want_access) if ((thd->master_access & want_access)) return 0; get_privilege_desc(command, sizeof(command), want_access); - my_printf_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, - ER(ER_SPECIFIC_ACCESS_DENIED_ERROR), MYF(0), command); + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command); return 1; #endif /* NO_EMBEDDED_ACCESS_CHECKS */ } @@ -4331,8 +4308,7 @@ check_sp_definer_access(THD *thd, sp_head *sp) strncmp(thd->priv_host, hst->str, hst->length) == 0) return FALSE; /* Both user and host must match */ - my_printf_error(ER_SP_ACCESS_DENIED_ERROR, ER(ER_SP_ACCESS_DENIED_ERROR), - MYF(0), sp->m_qname.str); + my_error(ER_SP_ACCESS_DENIED_ERROR, MYF(0), sp->m_qname.str); return TRUE; /* Not definer or root */ } @@ -4710,8 +4686,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if (strlen(field_name) > NAME_LEN) { - my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), - field_name); /* purecov: inspected */ + my_error(ER_TOO_LONG_IDENT, MYF(0), field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } if (type_modifier & PRI_KEY_FLAG) @@ -4742,8 +4717,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC && type == FIELD_TYPE_TIMESTAMP)) { - my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), - field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } else if (default_value->type() == Item::NULL_ITEM) @@ -4752,23 +4726,20 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) == NOT_NULL_FLAG) { - my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), - field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } else if (type_modifier & AUTO_INCREMENT_FLAG) { - my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), - field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } if (on_update_value && type != FIELD_TYPE_TIMESTAMP) { - my_printf_error(ER_INVALID_ON_UPDATE, ER(ER_INVALID_ON_UPDATE), MYF(0), - field_name); + my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name); DBUG_RETURN(1); } @@ -4894,9 +4865,8 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res=default_value->val_str(&str); if (res->length()) { - my_printf_error(ER_BLOB_CANT_HAVE_DEFAULT, - ER(ER_BLOB_CANT_HAVE_DEFAULT), MYF(0), - field_name); /* purecov: inspected */ + my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), + field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->def=0; @@ -4916,8 +4886,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, uint tmp_length=new_field->length; if (tmp_length > PRECISION_FOR_DOUBLE) { - my_printf_error(ER_WRONG_FIELD_SPEC, ER(ER_WRONG_FIELD_SPEC), MYF(0), - field_name); + my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); DBUG_RETURN(1); } else if (tmp_length > PRECISION_FOR_FLOAT) @@ -5014,8 +4983,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, { if (interval->count > sizeof(longlong)*8) { - my_printf_error(ER_TOO_BIG_SET, ER(ER_TOO_BIG_SET), MYF(0), - field_name); /* purecov: inspected */ + my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } new_field->pack_length=(interval->count+7)/8; @@ -5041,8 +5009,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, ¬_used, ¬_used2, ¬_used3); if (thd->cuted_fields) { - my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), - field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } @@ -5064,8 +5031,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, res->strip_sp(); if (!find_type(interval, res->ptr(), res->length(), 0)) { - my_printf_error(ER_INVALID_DEFAULT, ER(ER_INVALID_DEFAULT), MYF(0), - field_name); + my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); } } @@ -5079,15 +5045,14 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING && type != FIELD_TYPE_GEOMETRY)) { - my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH), MYF(0), + my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name, MAX_FIELD_CHARLENGTH);/* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } type_modifier&= AUTO_INCREMENT_FLAG; if ((~allowed_type_modifier) & type_modifier) { - my_printf_error(ER_WRONG_FIELD_SPEC, ER(ER_WRONG_FIELD_SPEC), MYF(0), - field_name); + my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name); DBUG_RETURN(1); } if (!new_field->pack_length) @@ -5217,8 +5182,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (check_table_name(table->table.str,table->table.length) || table->db.str && check_db_name(table->db.str)) { - my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), - table->table.str); + my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str); DBUG_RETURN(0); } @@ -5283,8 +5247,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) && !strcmp(ptr->db, tables->db)) { - my_printf_error(ER_NONUNIQ_TABLE, ER(ER_NONUNIQ_TABLE), MYF(0), - alias_str); /* purecov: tested */ + my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */ } } @@ -5828,8 +5791,7 @@ static bool append_file_to_dir(THD *thd, const char **filename_ptr, if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 || !test_if_hard_path(*filename_ptr)) { - my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), - *filename_ptr); + my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr); return 1; } /* Fix is using unix filename format on dos */ @@ -5863,8 +5825,7 @@ bool check_simple_select() char command[80]; strmake(command, lex->yylval->symbol.str, min(lex->yylval->symbol.length, sizeof(command)-1)); - my_printf_error(ER_CANT_USE_OPTION_HERE, ER(ER_CANT_USE_OPTION_HERE), - MYF(0), command); + my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command); return 1; } return 0; @@ -6010,7 +5971,7 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables) if (select_lex->item_list.elements != lex->value_list.elements) { - my_printf_error(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); + my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0)); DBUG_RETURN(TRUE); } /* @@ -6113,8 +6074,8 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count) } if (!walk) { - my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0), - target_tbl->real_name, "MULTI DELETE"); + my_error(ER_UNKNOWN_TABLE, MYF(0), + target_tbl->real_name, "MULTI DELETE"); DBUG_RETURN(TRUE); } walk->lock_type= target_tbl->lock_type; @@ -6288,8 +6249,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, find_table_in_global_list(tables, create_table->db, create_table->real_name)) { - net_printf(thd,ER_UPDATE_TABLE_USED, create_table->real_name); - + error= FALSE; goto err; } } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index e29f6329e58..9e3395cf893 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -926,9 +926,7 @@ static bool mysql_test_insert(Prepared_statement *stmt, counter++; if (values->elements != value_count) { - my_printf_error(ER_WRONG_VALUE_COUNT_ON_ROW, - ER(ER_WRONG_VALUE_COUNT_ON_ROW), - MYF(0), counter); + my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), counter); goto error; } if (setup_fields(thd, 0, table_list, *values, 0, 0, 0)) @@ -1062,15 +1060,13 @@ static int mysql_test_select(Prepared_statement *stmt, DBUG_RETURN(TRUE); #endif + result= TRUE; if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) - { - send_error(thd); goto err; - } - if ((result= open_and_lock_tables(thd, tables))) + if (open_and_lock_tables(thd, tables)) goto err; - result= TRUE; + thd->used_tables= 0; // Updated by setup_fields @@ -1518,9 +1514,8 @@ static bool init_param_array(Prepared_statement *stmt) if (stmt->param_count > (uint) UINT_MAX16) { /* Error code to be defined in 5.0 */ - send_error(thd, ER_UNKNOWN_ERROR, - "Prepared statement contains too many placeholders."); - return 1; + my_message(ER_PS_MANY_PARAM, ER(ER_PS_MANY_PARAM), MYF(0)); + return TRUE; } Item_param **to; List_iterator param_iterator(lex->param_list); @@ -1529,7 +1524,7 @@ static bool init_param_array(Prepared_statement *stmt) alloc_root(stmt->thd->mem_root, sizeof(Item_param*) * stmt->param_count); if (!stmt->param_array) - return 1; + return TRUE; for (to= stmt->param_array; to < stmt->param_array + stmt->param_count; ++to) @@ -1537,7 +1532,7 @@ static bool init_param_array(Prepared_statement *stmt) *to= param_iterator++; } } - return 0; + return FALSE; } @@ -1659,9 +1654,6 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); stmt= NULL; - if (thd->net.report_error) - send_error(thd); - /* otherwise the error is sent inside yyparse/check_preapred_statement */ } else { @@ -1968,7 +1960,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, alloc_query(thd, (char *)expanded_query->ptr(), expanded_query->length()+1)) { - my_error(ER_OUTOFMEMORY, 0, expanded_query->length()); + my_error(ER_OUTOFMEMORY, MYF(0), expanded_query->length()); DBUG_VOID_RETURN; } /* diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 25874e1335a..9f29a975441 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -157,8 +157,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) unpack_filename(name, name); if (!access(name,F_OK)) { - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - MYF(0), new_alias); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(ren_table); // This can't be skipped } sprintf(name,"%s/%s/%s%s",mysql_data_home, @@ -167,8 +166,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) unpack_filename(name, name); if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN) { - my_printf_error(ER_FILE_NOT_FOUND, ER(ER_FILE_NOT_FOUND), MYF(0), - name, my_errno); + my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); if (!skip_error) DBUG_RETURN(ren_table); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 3ef7e01d248..d2e3e72618d 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1002,7 +1002,7 @@ int reset_slave(THD *thd, MASTER_INFO* mi) err: unlock_slave_threads(mi); if (error) - my_printf_error(sql_errno, ER(sql_errno), MYF(0), errmsg); + my_error(sql_errno, MYF(0), errmsg); DBUG_RETURN(error); } @@ -1195,8 +1195,7 @@ bool change_master(THD* thd, MASTER_INFO* mi) 0 /* not only reset, but also reinit */, &errmsg)) { - my_printf_error(ER_RELAY_LOG_FAIL, ER(ER_RELAY_LOG_FAIL), MYF(0), - errmsg); + my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg); unlock_slave_threads(mi); DBUG_RETURN(TRUE); } @@ -1212,7 +1211,7 @@ bool change_master(THD* thd, MASTER_INFO* mi) 0 /*no data lock*/, &msg, 0)) { - my_printf_error(ER_RELAY_LOG_INIT, ER(ER_RELAY_LOG_INIT), MYF(0), msg); + my_error(ER_RELAY_LOG_INIT, MYF(0), msg); unlock_slave_threads(mi); DBUG_RETURN(TRUE); } @@ -1406,9 +1405,8 @@ err: if (errmsg) { - my_printf_error(ER_ERROR_WHEN_EXECUTING_COMMAND, - ER(ER_ERROR_WHEN_EXECUTING_COMMAND), MYF(0), - "SHOW BINLOG EVENTS", errmsg); + my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), + "SHOW BINLOG EVENTS", errmsg); DBUG_RETURN(TRUE); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f0584837028..2f3687c28bd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1883,7 +1883,7 @@ Cursor::fetch(ulong num_rows) thd->server_status&= ~SERVER_STATUS_LAST_ROW_SENT; } else - send_error(thd, ER_OUT_OF_RESOURCES); + my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); /* free cursor memory */ free_items(free_list); free_list= 0; @@ -11220,8 +11220,8 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, uint count= (uint) order_item->val_int(); if (!count || count > fields.elements) { - my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), - MYF(0), order_item->full_name(), thd->where); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + order_item->full_name(), thd->where); return 1; } order->item= ref_pointer_array + count - 1; @@ -11371,8 +11371,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, (*order->item)->marker=1; /* Mark found */ if ((*order->item)->with_sum_func) { - my_printf_error(ER_WRONG_GROUP_FIELD, ER(ER_WRONG_GROUP_FIELD),MYF(0), - (*order->item)->full_name()); + my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*order->item)->full_name()); return 1; } } @@ -11387,9 +11386,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, if (item->type() != Item::SUM_FUNC_ITEM && !item->marker && !item->const_item()) { - my_printf_error(ER_WRONG_FIELD_WITH_GROUP, - ER(ER_WRONG_FIELD_WITH_GROUP), - MYF(0),item->full_name()); + my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), item->full_name()); return 1; } } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b46834882c6..7a483086584 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -868,8 +868,8 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) /* TODO: add environment variables show when it become possible */ if (thd->lex->only_view && !table_list->view) { - my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), - table_list->db, table_list->real_name, "VIEW"); + my_error(ER_WRONG_OBJECT, MYF(0), + table_list->db, table_list->real_name, "VIEW"); DBUG_RETURN(TRUE); } @@ -938,7 +938,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, if (check_db_name(dbname)) { - my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), dbname); + my_error(ER_WRONG_DB_NAME, MYF(0), dbname); DBUG_RETURN(TRUE); } @@ -950,9 +950,8 @@ bool mysqld_show_create_db(THD *thd, char *dbname, thd->master_access); if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname))) { - my_printf_error(ER_DBACCESS_DENIED_ERROR, - ER(ER_DBACCESS_DENIED_ERROR), MYF(0), - thd->priv_user, thd->host_or_ip, dbname); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, thd->host_or_ip, dbname); mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), thd->priv_user, thd->host_or_ip, dbname); DBUG_RETURN(TRUE); @@ -969,7 +968,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, } if (access(path,F_OK)) { - my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), dbname); + my_error(ER_BAD_DB_ERROR, MYF(0), dbname); DBUG_RETURN(TRUE); } if (found_libchar) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 301130c13ca..cb327990a78 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -84,9 +84,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, { if (thd->global_read_lock) { - my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, - ER(ER_TABLE_NOT_LOCKED_FOR_WRITE), MYF(0), - tables->real_name); + my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->real_name); error= TRUE; goto err; } @@ -269,8 +267,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (wrong_tables.length()) { if (!foreign_key_error) - my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), - wrong_tables.c_ptr()); + my_error(ER_BAD_TABLE_ERROR, MYF(0), wrong_tables.c_ptr()); else my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0)); error= 1; @@ -470,8 +467,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (check_column_name(sql_field->field_name)) { - my_printf_error(ER_WRONG_COLUMN_NAME, ER(ER_WRONG_COLUMN_NAME), MYF(0), - sql_field->field_name); + my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name); DBUG_RETURN(-1); } @@ -488,8 +484,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (field_no < select_field_pos || dup_no >= select_field_pos) { - my_printf_error(ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME), MYF(0), - sql_field->field_name); + my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name); DBUG_RETURN(-1); } else @@ -541,8 +536,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_SPATIAL if (!(file->table_flags() & HA_CAN_GEOMETRY)) { - my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED), - MYF(0), "GEOMETRY"); + my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "GEOMETRY"); DBUG_RETURN(-1); } sql_field->pack_flag=FIELDFLAG_GEOM | @@ -555,8 +549,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, blob_columns++; break; #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); DBUG_RETURN(-1); #endif /*HAVE_SPATIAL*/ case FIELD_TYPE_VAR_STRING: @@ -676,11 +670,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (fk_key->ref_columns.elements && fk_key->ref_columns.elements != fk_key->columns.elements) { - my_printf_error(ER_WRONG_FK_DEF, ER(ER_WRONG_FK_DEF), MYF(0), - (fk_key->name ? - fk_key->name : - "foreign key without name"), - ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); + my_error(ER_WRONG_FK_DEF, MYF(0), + (fk_key->name ? fk_key->name : "foreign key without name"), + ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); DBUG_RETURN(-1); } continue; @@ -694,8 +686,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (key->name && strlen(key->name) > NAME_LEN) { - my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), - key->name); + my_error(ER_TOO_LONG_IDENT, MYF(0), key->name); DBUG_RETURN(-1); } key_iterator2.rewind (); @@ -735,8 +726,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, if (key->name && !tmp_table && !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { - my_printf_error(ER_WRONG_NAME_FOR_INDEX, ER(ER_WRONG_NAME_FOR_INDEX), - MYF(0), key->name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); DBUG_RETURN(-1); } } @@ -781,8 +771,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info->flags= HA_SPATIAL; break; #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); DBUG_RETURN(-1); #endif case Key::FOREIGN_KEY: @@ -822,8 +812,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (key_info->key_parts != 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX"); DBUG_RETURN(-1); } } @@ -833,17 +822,15 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_RTREE_KEYS if ((key_info->key_parts & 1) == 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); + my_error(ER_WRONG_ARGUMENTS, MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); } /* TODO: To be deleted */ - my_printf_error(ER_NOT_SUPPORTED_YET, ER(ER_NOT_SUPPORTED_YET), - MYF(0), "RTREE INDEX"); + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_rtree.name, sym_group_rtree.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_rtree.name, sym_group_rtree.needed_define); DBUG_RETURN(-1); #endif } @@ -861,9 +848,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, field++; if (!sql_field) { - my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, - ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0), - column->field_name); + my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name); DBUG_RETURN(-1); } /* for fulltext keys keyseg length is 1 for blobs (it's ignored in @@ -881,8 +866,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet (ft_key_charset && sql_field->charset != ft_key_charset)) { - my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0), - column->field_name); + my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name); DBUG_RETURN(-1); } ft_key_charset=sql_field->charset; @@ -903,15 +887,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->table_flags() & HA_CAN_INDEX_BLOBS)) { - my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0), - column->field_name); + my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name); DBUG_RETURN(-1); } if (!column->length) { - my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, - ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), - column->field_name); + my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name); DBUG_RETURN(-1); } } @@ -940,8 +921,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info->flags|= HA_NULL_PART_KEY; if (!(file->table_flags() & HA_NULL_IN_KEY)) { - my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), - MYF(0),column->field_name); + my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name); DBUG_RETURN(-1); } if (key->type == Key::SPATIAL) @@ -1001,8 +981,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } else if (length == 0) { - my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0), - column->field_name); + my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name); DBUG_RETURN(-1); } if (length > file->max_key_part_length()) @@ -1058,8 +1037,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key_info_buffer,key_info); if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) { - my_printf_error(ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), MYF(0), - key_name); + my_error(ER_DUP_KEYNAME, MYF(0), key_name); DBUG_RETURN(-1); } key_info->name=(char*) key_name; @@ -1067,8 +1045,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } if (!key_info->name || check_column_name(key_info->name)) { - my_printf_error(ER_WRONG_NAME_FOR_INDEX, ER(ER_WRONG_NAME_FOR_INDEX), - MYF(0), key_info->name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name); DBUG_RETURN(-1); } if (!(key_info->flags & HA_NULL_PART_KEY)) @@ -1177,7 +1154,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) && (file->table_flags() & HA_NO_TEMP_TABLES)) { - my_printf_error(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0), table_name); + my_error(ER_ILLEGAL_HA, MYF(0), table_name); DBUG_RETURN(TRUE); } #endif @@ -1228,8 +1205,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(FALSE); } - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), MYF(0), - alias); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); DBUG_RETURN(TRUE); } if (wait_if_global_read_lock(thd, 0, 1)) @@ -1245,8 +1221,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, error= FALSE; } else - my_printf_error(ER_TABLE_EXISTS_ERROR, - ER(ER_TABLE_EXISTS_ERROR), MYF(0), table_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); goto end; } } @@ -1275,8 +1250,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, error= FALSE; } else - my_printf_error(ER_TABLE_EXISTS_ERROR, - ER(ER_TABLE_EXISTS_ERROR), MYF(0), table_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); goto end; } } @@ -1495,8 +1469,7 @@ mysql_rename_table(enum db_type base, } delete file; if (error) - my_printf_error(ER_ERROR_ON_RENAME, ER(ER_ERROR_ON_RENAME), - MYF(0), from, to, error); + my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error); DBUG_RETURN(error != 0); } @@ -2048,8 +2021,7 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, if (!(key_cache= get_key_cache(key_cache_name))) { pthread_mutex_unlock(&LOCK_global_system_variables); - my_printf_error(ER_UNKNOWN_KEY_CACHE, ER(ER_UNKNOWN_KEY_CACHE), MYF(0), - key_cache_name->str); + my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str); DBUG_RETURN(TRUE); } pthread_mutex_unlock(&LOCK_global_system_variables); @@ -2159,8 +2131,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, check_table_name(src_table,table_ident->table.length)) || table_ident->db.str && check_db_name((src_db= table_ident->db.str))) { - my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), MYF(0), - src_table); + my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); DBUG_RETURN(TRUE); } @@ -2179,8 +2150,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, reg_ext, NullS); if (access(src_path, F_OK)) { - my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), - src_table); + my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); goto err; } } @@ -2263,8 +2233,7 @@ table_exists: res= FALSE; } else - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), MYF(0), - table_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name); err: pthread_mutex_lock(&LOCK_open); @@ -2523,8 +2492,7 @@ int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list, } if (idx>= table->keys) { - my_printf_error(ER_CANT_DROP_FIELD_OR_KEY, ER(ER_CANT_DROP_FIELD_OR_KEY), - MYF(0), drop_key->name); + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop_key->name); /*don't need to free((gptr) key_numbers);*/ DBUG_RETURN(-1); } @@ -2647,8 +2615,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (find_temporary_table(thd,new_db,new_name_buff)) { - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - MYF(0), new_name_buff); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff); DBUG_RETURN(TRUE); } } @@ -2660,8 +2627,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, F_OK)) { /* Table will be closed in do_command() */ - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - MYF(0), new_alias); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(TRUE); } } @@ -2702,8 +2668,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, error=0; if (!access(new_name_buff,F_OK)) { - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - MYF(0), new_name); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name); error= -1; } else @@ -2847,8 +2812,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (def->sql_type == FIELD_TYPE_BLOB) { - my_printf_error(ER_BLOB_CANT_HAVE_DEFAULT, - ER(ER_BLOB_CANT_HAVE_DEFAULT), MYF(0), def->change); + my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change); DBUG_RETURN(TRUE); } def->def=alter->def; // Use new default @@ -2862,8 +2826,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (def->change && ! def->field) { - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - def->change, table_name); + my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table_name); DBUG_RETURN(TRUE); } if (!def->after) @@ -2881,8 +2844,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } if (!find) { - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), - MYF(0), def->after, table_name); + my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table_name); DBUG_RETURN(TRUE); } find_it.after(def); // Put element after this @@ -2890,8 +2852,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } if (alter_info->alter_list.elements) { - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), - alter_info->alter_list.head()->name, table_name); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + alter_info->alter_list.head()->name, table_name); DBUG_RETURN(TRUE); } if (!create_list.elements) @@ -2986,8 +2948,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (key->name && !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { - my_printf_error(ER_WRONG_NAME_FOR_INDEX, ER(ER_WRONG_NAME_FOR_INDEX), - MYF(0), key->name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); DBUG_RETURN(TRUE); } } @@ -2995,16 +2956,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (alter_info->drop_list.elements) { - my_printf_error(ER_CANT_DROP_FIELD_OR_KEY, - ER(ER_CANT_DROP_FIELD_OR_KEY), MYF(0), - alter_info->drop_list.head()->name); + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), + alter_info->drop_list.head()->name); goto err; } if (alter_info->alter_list.elements) { - my_printf_error(ER_CANT_DROP_FIELD_OR_KEY, - ER(ER_CANT_DROP_FIELD_OR_KEY), MYF(0), - alter_info->alter_list.head()->name); + my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), + alter_info->alter_list.head()->name); goto err; } @@ -3207,8 +3166,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!access(new_name_buff,F_OK)) { error=1; - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - MYF(0), new_name_buff); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff); VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(pthread_mutex_unlock(&LOCK_open)); goto err; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 4a99296a7a5..7637679430f 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -74,8 +74,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) */ if (tables->view || table->tmp_table != NO_TMP_TABLE) { - my_printf_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, - ER(ER_TRG_ON_VIEW_OR_TEMP_TABLE), MYF(0), tables->alias); + my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); DBUG_RETURN(TRUE); } @@ -418,8 +417,8 @@ err_with_lex_cleanup: We don't care about this error message much because .TRG files will be merged into .FRM anyway. */ - my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), - table_name, triggers_file_ext, "TRIGGER"); + my_error(ER_WRONG_OBJECT, MYF(0), + table_name, triggers_file_ext, "TRIGGER"); DBUG_RETURN(1); } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 964021ce7fa..7fd81f22e66 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -384,15 +384,14 @@ int mysql_create_function(THD *thd,udf_func *udf) } if (udf->name.length > NAME_LEN) { - my_printf_error(ER_TOO_LONG_IDENT, ER(ER_TOO_LONG_IDENT), MYF(0), - udf->name); + my_error(ER_TOO_LONG_IDENT, MYF(0), udf->name); DBUG_RETURN(1); } rw_wrlock(&THR_LOCK_udf); if ((hash_search(&udf_hash,(byte*) udf->name.str, udf->name.length))) { - my_printf_error(ER_UDF_EXISTS, ER(ER_UDF_EXISTS), MYF(0), udf->name); + my_error(ER_UDF_EXISTS, MYF(0), udf->name); goto err; } if (!(dl = find_udf_dl(udf->dl))) @@ -401,7 +400,7 @@ int mysql_create_function(THD *thd,udf_func *udf) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", udf->dl,errno,dlerror())); - my_printf_error(ER_CANT_OPEN_LIBRARY, ER(ER_CANT_OPEN_LIBRARY), MYF(0), + my_error(ER_CANT_OPEN_LIBRARY, MYF(0), udf->dl, errno, dlerror()); goto err; } @@ -412,8 +411,7 @@ int mysql_create_function(THD *thd,udf_func *udf) if (udf->func == NULL) { - my_printf_error(ER_CANT_FIND_DL_ENTRY, ER(ER_CANT_FIND_DL_ENTRY), MYF(0), - udf->name); + my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), udf->name); goto err; } udf->name.str=strdup_root(&mem,udf->name.str); @@ -447,8 +445,7 @@ int mysql_create_function(THD *thd,udf_func *udf) close_thread_tables(thd); if (error) { - my_printf_error(ER_ERROR_ON_WRITE, ER(ER_ERROR_ON_WRITE), MYF(0), - "func@mysql", error); + my_error(ER_ERROR_ON_WRITE, MYF(0), "func@mysql", error); del_udf(u_d); goto err; } @@ -478,8 +475,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) if (!(udf=(udf_func*) hash_search(&udf_hash,(byte*) udf_name->str, (uint) udf_name->length))) { - my_printf_error(ER_FUNCTION_NOT_DEFINED, ER(ER_FUNCTION_NOT_DEFINED), - MYF(0), udf_name->str); + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), udf_name->str); goto err; } del_udf(udf); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index dfc46150847..c5167018701 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -38,15 +38,15 @@ static bool compare_record(TABLE *table, ulong query_id) if (memcmp(table->null_flags, table->null_flags+table->rec_buff_length, table->null_bytes)) - return 1; // Diff in NULL value + return TRUE; // Diff in NULL value /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { if ((*ptr)->query_id == query_id && (*ptr)->cmp_binary_offset(table->rec_buff_length)) - return 1; + return TRUE; } - return 0; + return FALSE; } @@ -73,8 +73,7 @@ static bool check_fields(THD *thd, List &items) if (!(field= item->filed_for_view_update())) { /* item has name, because it comes from VIEW SELECT list */ - my_printf_error(ER_NONUPDATEABLE_COLUMN, ER(ER_NONUPDATEABLE_COLUMN), - MYF(0), item->name); + my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name); return TRUE; } /* @@ -134,8 +133,8 @@ bool mysql_update(THD *thd, table_list->grant.want_privilege : table->grant.want_privilege); #endif - if ((error= mysql_prepare_update(thd, table_list, &conds, order_num, order))) - DBUG_RETURN(error); + if (mysql_prepare_update(thd, table_list, &conds, order_num, order)) + DBUG_RETURN(TRUE); old_used_keys= table->used_keys; // Keys used in WHERE /* @@ -165,8 +164,7 @@ bool mysql_update(THD *thd, } if (!table_list->updatable || check_key_in_view(thd, table_list)) { - my_printf_error(ER_NON_UPDATABLE_TABLE, ER(ER_NON_UPDATABLE_TABLE), - MYF(0), table_list->alias, "UPDATE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE"); DBUG_RETURN(TRUE); } if (table->timestamp_field) @@ -532,8 +530,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, /* Check that we are not using table that we are updating in a sub select */ if (unique_table(table_list, table_list->next_global)) { - my_printf_error(ER_UPDATE_TABLE_USED, ER(ER_UPDATE_TABLE_USED), MYF(0), - table_list->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name); DBUG_RETURN(TRUE); } select_lex->fix_prepare_information(thd, conds); @@ -591,7 +588,7 @@ bool mysql_multi_update_prepare(THD *thd) /* open tables and create derived ones, but do not lock and fill them */ if (open_tables(thd, table_list, & table_count) || mysql_handle_derived(lex, &mysql_derived_prepare)) - DBUG_RETURN(thd->net.report_error ? -1 : 1); + DBUG_RETURN(TRUE); /* Ensure that we have update privilege for all tables and columns in the SET part @@ -658,9 +655,7 @@ bool mysql_multi_update_prepare(THD *thd) { if (!tl->updatable || check_key_in_view(thd, tl)) { - my_printf_error(ER_NON_UPDATABLE_TABLE, - ER(ER_NON_UPDATABLE_TABLE), MYF(0), - tl->alias, "UPDATE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tl->alias, "UPDATE"); DBUG_RETURN(TRUE); } @@ -671,8 +666,7 @@ bool mysql_multi_update_prepare(THD *thd) if (lex->select_lex.check_updateable_in_subqueries(tl->db, tl->real_name)) { - my_printf_error(ER_UPDATE_TABLE_USED, - ER(ER_UPDATE_TABLE_USED), MYF(0), tl->real_name); + my_error(ER_UPDATE_TABLE_USED, MYF(0), tl->real_name); DBUG_RETURN(TRUE); } DBUG_PRINT("info",("setting table `%s` for update", tl->alias)); @@ -727,7 +721,7 @@ bool mysql_multi_update_prepare(THD *thd) } if (thd->fill_derived_tables() && mysql_handle_derived(lex, &mysql_derived_filling)) - DBUG_RETURN(thd->net.report_error ? -1 : 1); + DBUG_RETURN(TRUE); DBUG_RETURN (FALSE); } @@ -749,8 +743,8 @@ bool mysql_multi_update(THD *thd, multi_update *result; DBUG_ENTER("mysql_multi_update"); - if ((res= mysql_multi_update_prepare(thd))) - DBUG_RETURN(res); + if (mysql_multi_update_prepare(thd)) + DBUG_RETURN(TRUE); if (!(result= new multi_update(thd, table_list, fields, values, handle_duplicates))) @@ -1021,7 +1015,7 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List *fields) case JT_SYSTEM: case JT_CONST: case JT_EQ_REF: - return 1; // At most one matching row + return TRUE; // At most one matching row case JT_REF: return !check_if_key_used(table, join_tab->ref.key, *fields); case JT_ALL: @@ -1032,11 +1026,11 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List *fields) if ((table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) && table->primary_key < MAX_KEY) return !check_if_key_used(table, table->primary_key, *fields); - return 1; + return TRUE; default: break; // Avoid compler warning } - return 0; + return FALSE; } @@ -1360,7 +1354,7 @@ bool multi_update::send_eof() /* Safety: If we haven't got an error before (should not happen) */ my_message(ER_UNKNOWN_ERROR, "An error occured in multi-table update", MYF(0)); - return 1; + return TRUE; } @@ -1370,5 +1364,5 @@ bool multi_update::send_eof() (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; ::send_ok(thd, (ulong) thd->row_count_func, thd->insert_id_used ? thd->insert_id() : 0L,buff); - return 0; + return FALSE; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index cd739071d7b..f7f3a362696 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -113,13 +113,8 @@ bool mysql_create_view(THD *thd, */ if (check_some_access(thd, VIEW_ANY_ACL, tbl)) { - my_printf_error(ER_TABLEACCESS_DENIED_ERROR, - ER(ER_TABLEACCESS_DENIED_ERROR), - MYF(0), - "ANY", - thd->priv_user, - thd->host_or_ip, - tbl->real_name); + my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), + "ANY", thd->priv_user, thd->host_or_ip, tbl->real_name); DBUG_RETURN(TRUE); } /* @@ -190,8 +185,7 @@ bool mysql_create_view(THD *thd, /* is this table temporary and is not view? */ if (tbl->table->tmp_table != NO_TMP_TABLE && !tbl->view) { - my_printf_error(ER_VIEW_SELECT_TMPTABLE, - ER(ER_VIEW_SELECT_TMPTABLE), MYF(0), tbl->alias); + my_error(ER_VIEW_SELECT_TMPTABLE, MYF(0), tbl->alias); res= TRUE; goto err; } @@ -201,8 +195,7 @@ bool mysql_create_view(THD *thd, strcmp(tbl->view_db.str, view->db) == 0 && strcmp(tbl->view_name.str, view->real_name) == 0) { - my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), - tbl->view_db.str, tbl->view_name.str); + my_error(ER_NO_SUCH_TABLE, MYF(0), tbl->view_db.str, tbl->view_name.str); res= TRUE; goto err; } @@ -257,8 +250,7 @@ bool mysql_create_view(THD *thd, { if (strcmp(item->name, check->name) == 0) { - my_printf_error(ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME), - MYF(0), item->name); + my_error(ER_DUP_FIELDNAME, MYF(0), item->name); DBUG_RETURN(TRUE); } } @@ -290,14 +282,9 @@ bool mysql_create_view(THD *thd, if ((~fld->have_privileges & priv)) { /* VIEW column has more privileges */ - my_printf_error(ER_COLUMNACCESS_DENIED_ERROR, - ER(ER_COLUMNACCESS_DENIED_ERROR), - MYF(0), - "create view", - thd->priv_user, - thd->host_or_ip, - item->name, - view->real_name); + my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), + "create view", thd->priv_user, thd->host_or_ip, item->name, + view->real_name); DBUG_RETURN(TRUE); } } @@ -432,8 +419,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { if (mode == VIEW_CREATE_NEW) { - my_printf_error(ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - MYF(0), view->alias); + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), view->alias); DBUG_RETURN(-1); } @@ -443,9 +429,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (!parser->ok() || strncmp("VIEW", parser->type()->str, parser->type()->length)) { - my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), - (view->db ? view->db : thd->db), - view->real_name, "VIEW"); + my_error(ER_WRONG_OBJECT, MYF(0), + (view->db ? view->db : thd->db), view->real_name, "VIEW"); DBUG_RETURN(-1); } @@ -465,8 +450,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, { if (mode == VIEW_ALTER) { - my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), - view->db, view->alias); + my_error(ER_NO_SUCH_TABLE, MYF(0), view->db, view->alias); DBUG_RETURN(-1); } } @@ -529,8 +513,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, if (view->with_check != VIEW_CHECK_NONE && !view->updatable_view) { - my_printf_error(ER_VIEW_NONUPD_CHECK, ER(ER_VIEW_NONUPD_CHECK), MYF(0), - view->db, view->real_name); + my_error(ER_VIEW_NONUPD_CHECK, MYF(0), view->db, view->real_name); DBUG_RETURN(-1); } @@ -880,11 +863,9 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) continue; } if (type) - my_printf_error(ER_WRONG_OBJECT, ER(ER_WRONG_OBJECT), MYF(0), - view->db, view->real_name, "VIEW"); + my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->real_name, "VIEW"); else - my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0), - name); + my_error(ER_BAD_TABLE_ERROR, MYF(0), name); goto err; } if (my_delete(path, MYF(MY_WME))) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9974c7934dd..11c38a244a2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1467,8 +1467,7 @@ sp_fdparam: if (spc->find_pvar(&$1, TRUE)) { - my_printf_error(ER_SP_DUP_PARAM, ER(ER_SP_DUP_PARAM), MYF(0), - $1.str); + my_error(ER_SP_DUP_PARAM, MYF(0), $1.str); YYABORT; } spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in); @@ -1494,8 +1493,7 @@ sp_pdparam: if (spc->find_pvar(&$2, TRUE)) { - my_printf_error(ER_SP_DUP_PARAM, ER(ER_SP_DUP_PARAM), MYF(0), - $2.str); + my_error(ER_SP_DUP_PARAM, MYF(0), $2.str); YYABORT; } spc->push_pvar(&$2, (enum enum_field_types)$3, @@ -1588,8 +1586,7 @@ sp_decl: if (spc->find_cond(&$2, TRUE)) { - my_printf_error(ER_SP_DUP_COND, ER(ER_SP_DUP_COND), MYF(0), - $2.str); + my_error(ER_SP_DUP_COND, MYF(0), $2.str); YYABORT; } YYTHD->lex->spcont->push_cond(&$2, $5); @@ -1646,8 +1643,7 @@ sp_decl: if (ctx->find_cursor(&$2, &offp, TRUE)) { - my_printf_error(ER_SP_DUP_CURS, ER(ER_SP_DUP_CURS), MYF(0), - $2.str); + my_error(ER_SP_DUP_CURS, MYF(0), $2.str); delete $5; YYABORT; } @@ -1751,8 +1747,7 @@ sp_hcond: $$= Lex->spcont->find_cond(&$1); if ($$ == NULL) { - my_printf_error(ER_SP_COND_MISMATCH, ER(ER_SP_COND_MISMATCH), - MYF(0), $1.str); + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); YYABORT; } } @@ -1781,8 +1776,7 @@ sp_decl_idents: if (spc->find_pvar(&$1, TRUE)) { - my_printf_error(ER_SP_DUP_VAR, ER(ER_SP_DUP_VAR), MYF(0), - $1.str); + my_error(ER_SP_DUP_VAR, MYF(0), $1.str); YYABORT; } spc->push_pvar(&$1, (enum_field_types)0, sp_param_in); @@ -1795,8 +1789,7 @@ sp_decl_idents: if (spc->find_pvar(&$3, TRUE)) { - my_printf_error(ER_SP_DUP_VAR, ER(ER_SP_DUP_VAR), MYF(0), - $3.str); + my_error(ER_SP_DUP_VAR, MYF(0), $3.str); YYABORT; } spc->push_pvar(&$3, (enum_field_types)0, sp_param_in); @@ -1950,9 +1943,7 @@ sp_proc_stmt: if (! lab) { - my_printf_error(ER_SP_LILABEL_MISMATCH, - ER(ER_SP_LILABEL_MISMATCH), MYF(0), - "LEAVE", $2.str); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str); YYABORT; } else @@ -1982,9 +1973,7 @@ sp_proc_stmt: if (! lab || lab->type != SP_LAB_ITER) { - my_printf_error(ER_SP_LILABEL_MISMATCH, - ER(ER_SP_LILABEL_MISMATCH), MYF(0), - "ITERATE", $2.str); + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str); YYABORT; } else @@ -2012,8 +2001,7 @@ sp_proc_stmt: if (lab) { - my_printf_error(ER_SP_LABEL_REDEFINE, - ER(ER_SP_LABEL_REDEFINE), MYF(0), $2.str); + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $2.str); YYABORT; } else @@ -2088,8 +2076,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - my_printf_error(ER_SP_CURSOR_MISMATCH, - ER(ER_SP_CURSOR_MISMATCH), MYF(0), $2.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); YYABORT; } i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); @@ -2104,8 +2091,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$3, &offset)) { - my_printf_error(ER_SP_CURSOR_MISMATCH, - ER(ER_SP_CURSOR_MISMATCH), MYF(0), $3.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $3.str); YYABORT; } i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); @@ -2122,8 +2108,7 @@ sp_proc_stmt: if (! lex->spcont->find_cursor(&$2, &offset)) { - my_printf_error(ER_SP_CURSOR_MISMATCH, - ER(ER_SP_CURSOR_MISMATCH), MYF(0), $2.str); + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); YYABORT; } i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); @@ -2147,8 +2132,7 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$1))) { - my_printf_error(ER_SP_UNDECLARED_VAR, - ER(ER_SP_UNDECLARED_VAR), MYF(0), $1.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); YYABORT; } else @@ -2170,8 +2154,7 @@ sp_fetch_list: if (!spc || !(spv = spc->find_pvar(&$3))) { - my_printf_error(ER_SP_UNDECLARED_VAR, - ER(ER_SP_UNDECLARED_VAR), MYF(0), $3.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str); YYABORT; } else @@ -2295,8 +2278,7 @@ sp_labeled_control: if (lab) { - my_printf_error(ER_SP_LABEL_REDEFINE, - ER(ER_SP_LABEL_REDEFINE), MYF(0), $1.str); + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str); YYABORT; } else @@ -2317,8 +2299,7 @@ sp_labeled_control: if (!lab || my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) { - my_printf_error(ER_SP_LABEL_MISMATCH, - ER(ER_SP_LABEL_MISMATCH), MYF(0), $5.str); + my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); YYABORT; } } @@ -2576,11 +2557,9 @@ default_charset: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - my_printf_error(ER_CONFLICTING_DECLARATIONS, - ER(ER_CONFLICTING_DECLARATIONS), MYF(0), - "CHARACTER SET ", - cinfo->default_table_charset->csname, - "CHARACTER SET ", $4->csname); + my_error(ER_CONFLICTING_DECLARATIONS, MYF(0), + "CHARACTER SET ", cinfo->default_table_charset->csname, + "CHARACTER SET ", $4->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2595,9 +2574,8 @@ default_collation: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - my_printf_error(ER_COLLATION_CHARSET_MISMATCH, - ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), - $4->name, cinfo->default_table_charset->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $4->name, cinfo->default_table_charset->csname); YYABORT; } Lex->create_info.default_table_charset= $4; @@ -2609,8 +2587,7 @@ storage_engines: { $$ = ha_resolve_by_name($1.str,$1.length); if ($$ == DB_TYPE_UNKNOWN) { - my_printf_error(ER_UNKNOWN_STORAGE_ENGINE, - ER(ER_UNKNOWN_STORAGE_ENGINE), MYF(0), $1.str); + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str); YYABORT; } }; @@ -2807,10 +2784,8 @@ type: Lex->uint_geom_type= (uint)$1; $$=FIELD_TYPE_GEOMETRY; #else - my_printf_error(ER_FEATURE_DISABLED, - ER(ER_FEATURE_DISABLED), MYF(0) - sym_group_geom.name, - sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0) + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif } @@ -2977,9 +2952,8 @@ attribute: { if (Lex->charset && !my_charset_same(Lex->charset,$2)) { - my_printf_error(ER_COLLATION_CHARSET_MISMATCH, - ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), - $2->name,Lex->charset->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $2->name,Lex->charset->csname); YYABORT; } else @@ -3004,8 +2978,7 @@ charset_name: { if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) { - my_printf_error(ER_UNKNOWN_CHARACTER_SET, - ER(ER_UNKNOWN_CHARACTER_SET), MYF(0), $1.str); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); YYABORT; } } @@ -3023,8 +2996,7 @@ old_or_new_charset_name: if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) && !($$=get_old_charset_by_name($1.str))) { - my_printf_error(ER_UNKNOWN_CHARACTER_SET, - ER(ER_UNKNOWN_CHARACTER_SET), MYF(0), $1.str); + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); YYABORT; } } @@ -3040,8 +3012,7 @@ collation_name: { if (!($$=get_charset_by_name($1.str,MYF(0)))) { - my_printf_error(ER_UNKNOWN_COLLATION, - ER(ER_UNKNOWN_COLLATION), MYF(0), $1.str); + my_error(ER_UNKNOWN_COLLATION, MYF(0), $1.str); YYABORT; } }; @@ -3130,9 +3101,8 @@ key_type: #ifdef HAVE_SPATIAL $$= Key::SPATIAL; #else - my_printf_error(ER_FEATURE_DISABLED, - ER(ER_FEATURE_DISABLED), MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif }; @@ -3195,9 +3165,7 @@ key_part: int key_part_len= atoi($3.str); if (!key_part_len) { - my_printf_error(ER_UNKNOWN_ERROR, - "Key part '%s' length cannot be 0", - MYF(0), $1.str); + my_error(ER_KEY_PART_0, MYF(0), $1.str); } $$=new key_part_spec($1.str,(uint) key_part_len); }; @@ -3406,8 +3374,7 @@ alter_list_item: if (check_table_name($3->table.str,$3->table.length) || $3->db.str && check_db_name($3->db.str)) { - my_printf_error(ER_WRONG_TABLE_NAME, ER(ER_WRONG_TABLE_NAME), - MYF(0), $3->table.str); + my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); YYABORT; } lex->alter_info.flags|= ALTER_RENAME; @@ -3422,9 +3389,8 @@ alter_list_item: $5= $5 ? $5 : $4; if (!my_charset_same($4,$5)) { - my_printf_error(ER_COLLATION_CHARSET_MISMATCH, - ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), - $5->name, $4->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $5->name, $4->csname); YYABORT; } LEX *lex= Lex; @@ -4269,10 +4235,9 @@ simple_expr: { if (!$1.symbol->create_func) { - my_printf_error(ER_FEATURE_DISABLED, - ER(ER_FEATURE_DISABLED), MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(void))($1.symbol->create_func))(); @@ -4281,10 +4246,9 @@ simple_expr: { if (!$1.symbol->create_func) { - my_printf_error(ER_FEATURE_DISABLED, - ER(ER_FEATURE_DISABLED), MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*))($1.symbol->create_func))($3); @@ -4293,10 +4257,9 @@ simple_expr: { if (!$1.symbol->create_func) { - my_printf_error(ER_FEATURE_DISABLED, - ER(ER_FEATURE_DISABLED), MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5); @@ -4305,10 +4268,9 @@ simple_expr: { if (!$1.symbol->create_func) { - my_printf_error(ER_FEATURE_DISABLED, - ER(ER_FEATURE_DISABLED), MYF(0), - $1.symbol->group->name, - $1.symbol->group->needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + $1.symbol->group->name, + $1.symbol->group->needed_define); YYABORT; } $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7); @@ -4411,9 +4373,8 @@ simple_expr: #ifdef HAVE_SPATIAL $$= $1; #else - my_printf_error(ER_FEATURE_DISABLED, - ER(ER_FEATURE_DISABLED), MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); YYABORT; #endif } @@ -5469,8 +5430,7 @@ select_var_ident: if (!lex->spcont || !(t=lex->spcont->find_pvar(&$1))) { - my_printf_error(ER_SP_UNDECLARED_VAR, - ER(ER_SP_UNDECLARED_VAR), MYF(0), $1.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); YYABORT; } if (! lex->result) @@ -5826,9 +5786,8 @@ update: else if (lex->select_lex.get_table_list()->derived) { /* it is single table update and it is update of derived table */ - my_printf_error(ER_NON_UPDATABLE_TABLE, - ER(ER_NON_UPDATABLE_TABLE), MYF(0), - lex->select_lex.get_table_list()->alias, "UPDATE"); + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), + lex->select_lex.get_table_list()->alias, "UPDATE"); YYABORT; } else @@ -6686,9 +6645,8 @@ simple_ident_q: FIXME. Far from perfect solution. See comment for "SET NEW.field_name:=..." for more info. */ - my_printf_error(ER_BAD_FIELD_ERROR, - ER(ER_BAD_FIELD_ERROR), MYF(0), - $3.str, new_row ? "NEW": "OLD"); + my_error(ER_BAD_FIELD_ERROR, MYF(0), + $3.str, new_row ? "NEW": "OLD"); YYABORT; } @@ -6699,9 +6657,8 @@ simple_ident_q: SELECT_LEX *sel= lex->current_select; if (sel->no_table_names_allowed) { - my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, - ER(ER_TABLENAME_NOT_ALLOWED_HERE), - MYF(0), $1.str, thd->where); + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $1.str, thd->where); } $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? @@ -6716,9 +6673,8 @@ simple_ident_q: SELECT_LEX *sel= lex->current_select; if (sel->no_table_names_allowed) { - my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, - ER(ER_TABLENAME_NOT_ALLOWED_HERE), - MYF(0), $2.str, thd->where); + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $2.str, thd->where); } $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? @@ -6732,9 +6688,8 @@ simple_ident_q: SELECT_LEX *sel= lex->current_select; if (sel->no_table_names_allowed) { - my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, - ER(ER_TABLENAME_NOT_ALLOWED_HERE), - MYF(0), $3.str, thd->where); + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $3.str, thd->where); } $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? @@ -6775,9 +6730,8 @@ IDENT_sys: $1.length); if (wlen < $1.length) { - my_printf_error(ER_INVALID_CHARACTER_STRING, - ER(ER_INVALID_CHARACTER_STRING), MYF(0), - cs->csname, $1.str + wlen); + my_error(ER_INVALID_CHARACTER_STRING, MYF(0), + cs->csname, $1.str + wlen); YYABORT; } $$= $1; @@ -7214,8 +7168,7 @@ option_value: Error message also should be improved. */ - my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), - MYF(0), $1.base_name, "NEW"); + my_error(ER_BAD_FIELD_ERROR, MYF(0), $1.base_name, "NEW"); YYABORT; } lex->sphead->add_instr(i); @@ -7281,9 +7234,8 @@ option_value: $3= $3 ? $3 : $2; if (!my_charset_same($2,$3)) { - my_printf_error(ER_COLLATION_CHARSET_MISMATCH, - ER(ER_COLLATION_CHARSET_MISMATCH), MYF(0), - $3->name, $2->csname); + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $3->name, $2->csname); YYABORT; } lex->var_list.push_back(new set_var_collation_client($3,$3,$3)); @@ -7373,8 +7325,7 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - my_printf_error(ER_VARIABLE_IS_NOT_STRUCT, - ER(ER_VARIABLE_IS_NOT_STRUCT), MYF(0), $3.str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); $$.var= tmp; $$.base_name= $1; } @@ -7385,8 +7336,7 @@ internal_variable_name: if (!tmp) YYABORT; if (!tmp->is_struct()) - my_printf_error(ER_VARIABLE_IS_NOT_STRUCT, - ER(ER_VARIABLE_IS_NOT_STRUCT), MYF(0), $3.str); + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); $$.var= tmp; $$.base_name.str= (char*) "default"; $$.base_name.length= 7; diff --git a/sql/table.cc b/sql/table.cc index 095c3f037d5..e9ce118183f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -984,12 +984,11 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype) uint length=dirname_part(buff,name); buff[length-1]=0; db=buff+dirname_length(buff); - my_printf_error(ER_NO_SUCH_TABLE, ER(ER_NO_SUCH_TABLE), MYF(0), - db, form->real_name); + my_error(ER_NO_SUCH_TABLE, MYF(0), db, form->real_name); } else - my_printf_error(ER_FILE_NOT_FOUND, ER(ER_FILE_NOT_FOUND), errortype, - fn_format(buff, name, form_dev, reg_ext, 0), my_errno); + my_error(ER_FILE_NOT_FOUND, errortype, + fn_format(buff, name, form_dev, reg_ext, 0), my_errno); break; case 2: { @@ -997,15 +996,14 @@ static void frm_error(int error, TABLE *form, const char *name, myf errortype) datext= datext==NullS ? "" : datext; err_no= (my_errno == ENOENT) ? ER_FILE_NOT_FOUND : (my_errno == EAGAIN) ? ER_FILE_USED : ER_CANT_OPEN_FILE; - my_printf_error(err_no, ER(err_no), errortype, - fn_format(buff, form->real_name, form_dev, datext, 2), - my_errno); + my_error(err_no, errortype, + fn_format(buff, form->real_name, form_dev, datext, 2), my_errno); break; } default: /* Better wrong error than none */ case 4: - my_printf_error(ER_NOT_FORM_FILE, ER(ER_NOT_FORM_FILE), errortype, - fn_format(buff, name, form_dev, reg_ext, 0)); + my_error(ER_NOT_FORM_FILE, errortype, + fn_format(buff, name, form_dev, reg_ext, 0)); break; } DBUG_VOID_RETURN; @@ -1728,8 +1726,7 @@ err: if (thd->net.last_errno == ER_BAD_FIELD_ERROR) { thd->clear_error(); - my_printf_error(ER_VIEW_INVALID, ER(ER_VIEW_INVALID), MYF(0), - view_db.str, view_name.str); + my_error(ER_VIEW_INVALID, MYF(0), view_db.str, view_name.str); } thd->lex->select_lex.no_wrap_view_item= save_wrapper; thd->lex->current_select= current_select_save; @@ -1783,8 +1780,7 @@ int st_table_list::view_check_option(THD *thd, bool ignore_failure) } else { - my_printf_error(ER_VIEW_CHECK_FAILED, ER(ER_VIEW_CHECK_FAILED), MYF(0), - view_db.str, view_name.str); + my_error(ER_VIEW_CHECK_FAILED, MYF(0), view_db.str, view_name.str); return(VIEW_CHECK_ERROR); } } -- cgit v1.2.1 From d18a91a90c9e2372f3df7b89d16b9941c87355fc Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 13 Nov 2004 23:26:15 +0200 Subject: posmerge fixes mysql-test/r/view.result: erorr reported sql/item.cc: removed starnge code sql/mysql_priv.h: now error represented by Bool value sql/sql_parse.cc: removed old send_error calls sql/sql_select.cc: removed starnge code sql/sql_show.cc: show functions fixed sql/table.h: now error represented by Bool value --- sql/item.cc | 3 -- sql/mysql_priv.h | 2 +- sql/sql_parse.cc | 24 +++++++++------- sql/sql_select.cc | 3 -- sql/sql_show.cc | 85 ++++++++++++++++++++++++++++++------------------------- sql/table.h | 2 +- 6 files changed, 62 insertions(+), 57 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 42e1f23babd..ea721eea831 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1793,9 +1793,6 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference) !any_privileges)) == not_found_field) { -#ifdef EMBEDDED_LIBRARY - thd->net.last_errno= 0; -#endif SELECT_LEX *last= 0; TABLE_LIST *table_list; Item **ref= (Item **) not_found_item; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index d3ff1a0ab0a..7a49799c7cd 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -737,7 +737,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond); int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond); int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond); int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond); -int get_schema_tables_result(JOIN *join); +bool get_schema_tables_result(JOIN *join); /* sql_prepare.cc */ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index dfd82f2750e..11c02dacdad 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1877,7 +1877,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, switch(schema_table_idx) { case SCH_SCHEMATA: #if defined(DONT_ALLOW_SHOW_COMMANDS) - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, + ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); #else if ((specialflag & SPECIAL_SKIP_SHOW_DB) && @@ -1889,30 +1890,30 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, case SCH_TABLES: case SCH_VIEWS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, + ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); #else { char *db= lex->select_lex.db ? lex->select_lex.db : thd->db; if (!db) { - send_error(thd,ER_NO_DB_ERROR); /* purecov: inspected */ + my_message(ER_NO_DB_ERROR, + ER(ER_NO_DB_ERROR), MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */ } remove_escape(db); // Fix escaped '_' if (check_db_name(db)) { - net_printf(thd,ER_WRONG_DB_NAME, db); + my_error(ER_WRONG_DB_NAME, MYF(0), db); DBUG_RETURN(1); } if (check_access(thd,SELECT_ACL,db,&thd->col_access,0,0)) DBUG_RETURN(1); /* purecov: inspected */ if (!thd->col_access && check_grant_db(thd,db)) { - net_printf(thd, ER_DBACCESS_DENIED_ERROR, - thd->priv_user, - thd->priv_host, - db); + my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), + thd->priv_user, thd->priv_host, db); DBUG_RETURN(1); } lex->select_lex.db= db; @@ -1922,7 +1923,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident, case SCH_COLUMNS: case SCH_STATISTICS: #ifdef DONT_ALLOW_SHOW_COMMANDS - send_error(thd,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ + my_message(ER_NOT_ALLOWED_COMMAND, + ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */ DBUG_RETURN(1); #else if (table_ident) @@ -5238,8 +5240,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->real_name); if (!schema_table) { - net_printf(thd, ER_UNKNOWN_TABLE, ptr->real_name, - information_schema_name.str); + my_error(ER_UNKNOWN_TABLE, MYF(0), + ptr->real_name, information_schema_name.str); DBUG_RETURN(0); } ptr->schema_table= schema_table; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 977e8c5c9ca..bb620617db3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9770,9 +9770,6 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { Item *item= *group->item; item->save_org_in_field(group->field); -#ifdef EMBEDDED_LIBRARY - join->thd->net.last_errno= 0; -#endif /* Store in the used key if the field was 0 */ if (item->maybe_null) group->buff[-1]=item->null_value ? 1 : 0; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 4af041d1a95..c92369685ea 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1900,7 +1900,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) TABLE *old_open_tables= thd->open_tables; TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first; lex->all_selects_list= lsel; - int res= open_and_lock_tables(thd, show_table_list); + bool res= open_and_lock_tables(thd, show_table_list); if (schema_table->process_table(thd, show_table_list, table, res, show_table_list->db, show_table_list->real_name)) @@ -2060,9 +2060,10 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) } -int get_schema_tables_record(THD *thd, struct st_table_list *tables, - TABLE *table, int res, - const char *base_name, const char *file_name) +static int get_schema_tables_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) { const char *tmp_buff; TIME time; @@ -2070,18 +2071,21 @@ int get_schema_tables_record(THD *thd, struct st_table_list *tables, DBUG_ENTER("get_schema_tables_record"); restore_record(table, default_values); - if (res > 0) - { - DBUG_RETURN(1); - } table->field[1]->store(base_name, strlen(base_name), cs); table->field[2]->store(file_name, strlen(file_name), cs); - if (res < 0 || tables->view) + if (res) + { + /* + there was errors during opening tables + */ + const char *error= thd->net.last_error; + table->field[20]->store(error, strlen(error), cs); + thd->clear_error(); + } + else if (tables->view) { table->field[3]->store("VIEW", 4, cs); table->field[20]->store("view", 4, cs); - if (res) - thd->clear_error(); } else { @@ -2203,9 +2207,10 @@ int get_schema_tables_record(THD *thd, struct st_table_list *tables, } -int get_schema_column_record(THD *thd, struct st_table_list *tables, - TABLE *table, int res, - const char *base_name, const char *file_name) +static int get_schema_column_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) { TIME time; const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS; @@ -2538,9 +2543,10 @@ err: } -int get_schema_stat_record(THD *thd, struct st_table_list *tables, - TABLE *table, int res, - const char *base_name, const char *file_name) +static int get_schema_stat_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_stat_record"); @@ -2605,13 +2611,14 @@ int get_schema_stat_record(THD *thd, struct st_table_list *tables, } } } - DBUG_RETURN(0); + DBUG_RETURN(res); } -int get_schema_views_record(THD *thd, struct st_table_list *tables, - TABLE *table, int res, - const char *base_name, const char *file_name) +static int get_schema_views_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_views_record"); @@ -2631,13 +2638,14 @@ int get_schema_views_record(THD *thd, struct st_table_list *tables, table->file->write_row(table->record[0]); } } - DBUG_RETURN(0); + DBUG_RETURN(res); } -int get_schema_constarints_record(THD *thd, struct st_table_list *tables, - TABLE *table, int res, - const char *base_name, const char *file_name) +static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_constarints_record"); @@ -2684,14 +2692,15 @@ int get_schema_constarints_record(THD *thd, struct st_table_list *tables, table->file->write_row(table->record[0]); } } - DBUG_RETURN(0); + DBUG_RETURN(res); } -int get_schema_key_column_usage_record(THD *thd, struct st_table_list *tables, - TABLE *table, int res, - const char *base_name, - const char *file_name) +static int get_schema_key_column_usage_record(THD *thd, + struct st_table_list *tables, + TABLE *table, bool res, + const char *base_name, + const char *file_name) { DBUG_ENTER("get_schema_key_column_usage_record"); CHARSET_INFO *cs= system_charset_info; @@ -2707,7 +2716,7 @@ int get_schema_key_column_usage_record(THD *thd, struct st_table_list *tables, for (uint i=0 ; i < show_table->keys ; i++, key_info++) { if (i != primary_key && !(key_info->flags & HA_NOSAME)) - continue; + continue; uint f_idx= 0; KEY_PART_INFO *key_part= key_info->key_part; for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) @@ -2762,7 +2771,7 @@ int get_schema_key_column_usage_record(THD *thd, struct st_table_list *tables, } } } - DBUG_RETURN(0); + DBUG_RETURN(res); } @@ -3076,11 +3085,11 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, join join which use schema tables RETURN - 0 success - 1 error + FALSE success + TRUE error */ -int get_schema_tables_result(JOIN *join) +bool get_schema_tables_result(JOIN *join) { DBUG_ENTER("get_schema_tables_result"); JOIN_TAB *tmp_join_tab= join->join_tab+join->tables; @@ -3090,7 +3099,7 @@ int get_schema_tables_result(JOIN *join) if (!tab->table || !tab->table->pos_in_table_list) break; TABLE_LIST *table_list= tab->table->pos_in_table_list; - if (table_list->schema_table && !thd->only_prepare()) + if (table_list->schema_table && thd->fill_derived_tables()) { TABLE *old_derived_tables= thd->derived_tables; thd->derived_tables= 0; @@ -3103,14 +3112,14 @@ int get_schema_tables_result(JOIN *join) { thd->derived_tables= old_derived_tables; thd->lock= sql_lock; - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); } thd->lock= sql_lock; thd->lex->sql_command= SQLCOM_SELECT; thd->derived_tables= old_derived_tables; } } - DBUG_RETURN(0); + DBUG_RETURN(FALSE); } diff --git a/sql/table.h b/sql/table.h index 86dd30dff68..db3ce638842 100644 --- a/sql/table.h +++ b/sql/table.h @@ -250,7 +250,7 @@ typedef struct st_schema_table /* Handle fileds for old SHOW */ int (*old_format) (THD *thd, struct st_schema_table *schema_table); int (*process_table) (THD *thd, struct st_table_list *tables, - TABLE *table, int res, const char *base_name, + TABLE *table, bool res, const char *base_name, const char *file_name); int idx_field1, idx_field2; } ST_SCHEMA_TABLE; -- cgit v1.2.1 From 9ec34a400aa386ce539176632f5dda830912cc2c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 14 Nov 2004 00:28:44 +0200 Subject: make information schema libmysqld compatible fixed typo sql/handler.cc: fixed typo sql/sql_acl.cc: make information schema libmysqld compatible --- sql/handler.cc | 4 ++-- sql/sql_acl.cc | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index e65fd6d097d..12820a66cb9 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -517,8 +517,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if ((error=ndbcluster_commit(thd,trans->ndb_tid))) { if (error == -1) - my_message_(ER_ERROR_DURING_COMMIT, ER(ER_ERROR_DURING_COMMIT), - MYF(0)); + my_message(ER_ERROR_DURING_COMMIT, ER(ER_ERROR_DURING_COMMIT), + MYF(0)); error=1; } if (trans == &thd->transaction.all) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4c6ba829793..036ccb91260 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3985,8 +3985,10 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } -#endif DBUG_RETURN(0); +#else + return(0); +#endif } @@ -4033,8 +4035,10 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } -#endif DBUG_RETURN(0); +#else + return (0); +#endif } @@ -4078,8 +4082,10 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } -#endif DBUG_RETURN(0); +#else + return (0); +#endif } @@ -4135,8 +4141,10 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) } } } -#endif DBUG_RETURN(0); +#else + return (0); +#endif } -- cgit v1.2.1 From a59b0fbfd6b7627a4fdf2233482e732480dbe437 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 15 Nov 2004 19:20:45 +0300 Subject: Fixes for information_schema sql/sql_acl.cc: Fix for bug 'If user has column privilege with grant option is_grantable is 'NO' in INFORMATION_SCHEMA.COLUMN_PRIVILEGES' sql/sql_show.cc: removed sprinf Fix for 'sp with select from information_schema table crashes server' typo fixes --- sql/sql_acl.cc | 4 ++-- sql/sql_show.cc | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 15 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 036ccb91260..8ffba2579f3 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -4107,10 +4107,10 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ulong table_access= grant_table->cols; if (table_access != 0) { - ulong test_access= grant_table->cols & ~GRANT_ACL; - if (!(table_access & GRANT_ACL)) + if (!(grant_table->privs & GRANT_ACL)) is_grantable= "NO"; + ulong test_access= table_access & ~GRANT_ACL; strxmov(buff,"'",user,"'@'",grant_table->orig_host,"'",NullS); if (!test_access) continue; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c92369685ea..17e6866f565 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1891,10 +1891,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) LEX *lex= thd->lex; TABLE *table= tables->table; SELECT_LEX *select_lex= &lex->select_lex; + SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; DBUG_ENTER("fill_schema_tables"); - SELECT_LEX *lsel= tables->schema_select_lex; if (lsel) { TABLE *old_open_tables= thd->open_tables; @@ -1947,7 +1947,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) #endif { List files; - (void) sprintf(path,"%s/%s",mysql_data_home,base_name); + strxmov(path, mysql_data_home, "/", base_name, NullS); end= path + (len= unpack_dirname(path,path)); len= FN_LEN - len; if (mysql_find_files(thd, &files, base_name, @@ -2035,7 +2035,7 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) (grant_option && !check_grant_db(thd, file_name))) #endif { - (void) sprintf(path,"%s/%s",mysql_data_home, file_name); + strxmov(path, mysql_data_home, "/", file_name, NullS); length=unpack_dirname(path,path); // Convert if not unix found_libchar= 0; if (length && path[length-1] == FN_LIBCHAR) @@ -2050,8 +2050,8 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) load_db_opt(thd, path, &create); restore_record(table, default_values); table->field[1]->store(file_name, strlen(file_name), system_charset_info); - table->field[2]->store(create.default_table_charset->name, - strlen(create.default_table_charset->name), + table->field[2]->store(create.default_table_charset->csname, + strlen(create.default_table_charset->csname), system_charset_info); table->file->write_row(table->record[0]); } @@ -2187,9 +2187,10 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables, if (file->raid_type) { char buff[100]; - sprintf(buff," raid_type=%s raid_chunks=%d raid_chunksize=%ld", - my_raid_type(file->raid_type), file->raid_chunks, - file->raid_chunksize/RAID_BLOCK_SIZE); + my_snprintf(buff,sizeof(buff), + " raid_type=%s raid_chunks=%d raid_chunksize=%ld", + my_raid_type(file->raid_type), file->raid_chunks, + file->raid_chunksize/RAID_BLOCK_SIZE); ptr=strmov(ptr,buff); } table->field[19]->store(option_buff+1, @@ -2630,7 +2631,17 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, table->field[1]->store(tables->view_db.str, tables->view_db.length, cs); table->field[2]->store(tables->view_name.str,tables->view_name.length,cs); table->field[3]->store(tables->query.str, tables->query.length, cs); - table->field[4]->store("NONE", 4, cs); + + if (tables->with_check != VIEW_CHECK_NONE) + { + if (tables->with_check == VIEW_CHECK_LOCAL) + table->field[4]->store("WITH LOCAL CHECK OPTION", 23, cs); + else + table->field[4]->store("WITH CASCADED CHECK OPTION", 26, cs); + } + else + table->field[4]->store("NONE", 4, cs); + if (tables->updatable_view) table->field[5]->store("YES", 3, cs); else @@ -2668,7 +2679,7 @@ static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, table->field[3]->store(base_name, strlen(base_name), cs); table->field[4]->store(file_name, strlen(file_name), cs); if (i == primary_key && !strcmp(key_info->name, primary_key_name)) - table->field[5]->store("PRIMARY", 7, cs); + table->field[5]->store("PRIMARY KEY", 11, cs); else if (key_info->flags & HA_NOSAME) table->field[5]->store("UNIQUE", 6, cs); table->file->write_row(table->record[0]); @@ -2685,7 +2696,7 @@ static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, f_key_info->forein_id->length, cs); table->field[3]->store(base_name, strlen(base_name), cs); table->field[4]->store(file_name, strlen(file_name), cs); - table->field[5]->store("FOREIGN", 7, system_charset_info); + table->field[5]->store("FOREIGN KEY", 11, system_charset_info); table->field[6]->store(f_key_info->constraint_method->str, f_key_info->constraint_method->length, cs); table->field[6]->set_notnull(); @@ -3099,6 +3110,8 @@ bool get_schema_tables_result(JOIN *join) if (!tab->table || !tab->table->pos_in_table_list) break; TABLE_LIST *table_list= tab->table->pos_in_table_list; + TABLE_LIST *save_next_global= table_list->next_global; + if (table_list->schema_table && thd->fill_derived_tables()) { TABLE *old_derived_tables= thd->derived_tables; @@ -3112,11 +3125,13 @@ bool get_schema_tables_result(JOIN *join) { thd->derived_tables= old_derived_tables; thd->lock= sql_lock; + table_list->next_global= save_next_global; DBUG_RETURN(TRUE); } thd->lock= sql_lock; thd->lex->sql_command= SQLCOM_SELECT; thd->derived_tables= old_derived_tables; + table_list->next_global= save_next_global; } } DBUG_RETURN(FALSE); @@ -3178,7 +3193,7 @@ ST_FIELD_INFO columns_fields_info[]= {"KEY", 3, MYSQL_TYPE_STRING, 0, 0, 1, "Key"}, {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 1, "Default"}, {"EXTRA", 20, MYSQL_TYPE_STRING, 0, 0, 1, "Extra"}, - {"PRIVILIGES", 80, MYSQL_TYPE_STRING, 0, 0, 1, "Privileges"}, + {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, 1, "Privileges"}, {"COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, 1, "Comment"}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} }; @@ -3265,7 +3280,7 @@ ST_FIELD_INFO view_fields_info[]= {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 1, 0}, {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 1, 0}, - {"CHECK_OPTION", 4, MYSQL_TYPE_STRING, 0, 0, 1, 0}, + {"CHECK_OPTION", 30, MYSQL_TYPE_STRING, 0, 0, 1, 0}, {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 1, 0}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} }; -- cgit v1.2.1