2745 Konstantin Osipov 2008-11-14
A pre-requisite patch for WL#4264 "Backup: Stabilize Service Interface"
Move all warning-related information to Warning_info structure,
to be able to reset and restore this structure.
modified:
libmysqld/emb_qcache.cc
libmysqld/lib_sql.cc
mysql-test/r/query_cache.result
sql/backup/kernel.cc
sql/event_scheduler.cc
sql/field.cc
sql/ha_ndbcluster_binlog.cc
sql/handler.cc
sql/log.cc
sql/log_event.cc
sql/mysqld.cc
sql/protocol.cc
sql/set_var.cc
sql/slave.cc
sql/sp.cc
sql/sp_rcontext.cc
sql/sp_rcontext.h
sql/sql_acl.cc
sql/sql_base.cc
sql/sql_class.cc
sql/sql_class.h
sql/sql_error.cc
sql/sql_error.h
sql/sql_insert.cc
sql/sql_load.cc
sql/sql_parse.cc
sql/sql_prepare.cc
sql/sql_select.cc
sql/sql_show.cc
sql/sql_table.cc
sql/sql_update.cc
sql/time.cc
sql/unireg.cc
2744 Alexander Nozdrin 2008-11-12 [merge]
Pull from 6.0
modified:
mysys/my_init.c
sql/sql_cache.cc
=== modified file 'libmysqld/emb_qcache.cc'
--- a/libmysqld/emb_qcache.cc 2008-07-10 23:45:24 +0000
+++ b/libmysqld/emb_qcache.cc 2008-11-14 20:45:00 +0000
@@ -483,7 +483,8 @@ int emb_load_querycache_result(THD *thd,
*prev_row= NULL;
data->embedded_info->prev_ptr= prev_row;
return_ok:
- net_send_eof(thd, thd->server_status, thd->total_warn_count);
+ net_send_eof(thd, thd->server_status,
+ thd->warning_info.statement_warn_count());
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc 2008-09-04 18:30:34 +0000
+++ b/libmysqld/lib_sql.cc 2008-11-14 20:45:00 +0000
@@ -208,7 +208,7 @@ static my_bool emb_read_prepare_result(M
stmt->stmt_id= thd->client_stmt_id;
stmt->param_count= thd->client_param_count;
stmt->field_count= 0;
- mysql->warning_count= thd->total_warn_count;
+ mysql->warning_count= thd->warning_info.statement_warn_count();
if (thd->first_data)
{
@@ -797,7 +797,7 @@ MYSQL_DATA *THD::alloc_new_dataset()
static
void
-write_eof_packet(THD *thd, uint server_status, uint total_warn_count)
+write_eof_packet(THD *thd, uint server_status, uint statement_warn_count)
{
if (!thd->mysql) // bootstrap file handling
return;
@@ -814,7 +814,7 @@ write_eof_packet(THD *thd, uint server_s
is cleared between substatements, and mysqltest gets confused
*/
thd->cur_data->embedded_info->warning_count=
- (thd->spcont ? 0 : min(total_warn_count, 65535));
+ (thd->spcont ? 0 : min(statement_warn_count, 65535));
}
@@ -970,7 +970,8 @@ bool Protocol::send_result_set_metadata(
}
if (flags & SEND_EOF)
- write_eof_packet(thd, thd->server_status, thd->total_warn_count);
+ write_eof_packet(thd, thd->server_status,
+ thd->warning_info.statement_warn_count());
DBUG_RETURN(prepare_for_send(list->elements));
err:
@@ -1030,7 +1031,7 @@ bool Protocol_binary::write()
void
net_send_ok(THD *thd,
- uint server_status, uint total_warn_count,
+ uint server_status, uint statement_warn_count,
ha_rows affected_rows, ulonglong id, const char *message)
{
DBUG_ENTER("emb_net_send_ok");
@@ -1047,7 +1048,7 @@ net_send_ok(THD *thd,
strmake(data->embedded_info->info, message,
sizeof(data->embedded_info->info)-1);
- write_eof_packet(thd, server_status, total_warn_count);
+ write_eof_packet(thd, server_status, statement_warn_count);
thd->cur_data= 0;
DBUG_VOID_RETURN;
}
@@ -1062,9 +1063,9 @@ net_send_ok(THD *thd,
*/
void
-net_send_eof(THD *thd, uint server_status, uint total_warn_count)
+net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
{
- write_eof_packet(thd, server_status, total_warn_count);
+ write_eof_packet(thd, server_status, statement_warn_count);
thd->cur_data= 0;
}
=== modified file 'mysql-test/r/query_cache.result'
--- a/mysql-test/r/query_cache.result 2008-10-20 09:16:47 +0000
+++ b/mysql-test/r/query_cache.result 2008-11-14 20:45:00 +0000
@@ -942,19 +942,19 @@ COUNT(*)
0
Warnings:
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
-Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 0
+Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid';
COUNT(*)
0
Warnings:
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
-Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 0
+Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid';
COUNT(*)
0
Warnings:
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
-Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 0
+Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc 2008-11-06 18:39:27 +0000
+++ b/sql/backup/kernel.cc 2008-11-14 20:45:00 +0000
@@ -490,7 +490,7 @@ int Backup_restore_ctx::prepare(String *
// Prepare error reporting context.
- mysql_reset_errors(m_thd, 0); // Never errors
+ m_thd->warning_info.opt_clear_warning_info(m_thd->query_id); // Never errors
m_thd->no_warnings_for_error= FALSE;
save_errors(); // Never errors
=== modified file 'sql/event_scheduler.cc'
--- a/sql/event_scheduler.cc 2008-10-21 08:51:31 +0000
+++ b/sql/event_scheduler.cc 2008-11-14 20:45:00 +0000
@@ -74,7 +74,7 @@ Event_worker_thread::print_warnings(THD
{
MYSQL_ERROR *err;
DBUG_ENTER("evex_print_warnings");
- if (!thd->warn_list.elements)
+ if (thd->warning_info.is_empty())
DBUG_VOID_RETURN;
char msg_buf[10 * STRING_BUFFER_USUAL_SIZE];
@@ -90,7 +90,7 @@ Event_worker_thread::print_warnings(THD
prefix.append(et->name.str, et->name.length, system_charset_info);
prefix.append("] ", 2);
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
while ((err= it++))
{
String err_msg(msg_buf, sizeof(msg_buf), system_charset_info);
=== modified file 'sql/field.cc'
--- a/sql/field.cc 2008-11-06 18:39:27 +0000
+++ b/sql/field.cc 2008-11-14 20:45:00 +0000
@@ -1116,7 +1116,7 @@ int Field_num::check_int(CHARSET_INFO *c
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"integer", tmp.c_ptr(), field_name,
- (ulong) table->in_use->row_count);
+ table->in_use->warning_info.current_row_for_warning());
return 1;
}
/* Test if we have garbage at the end of the given string. */
@@ -2599,7 +2599,7 @@ int Field_new_decimal::store(const char
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"decimal", from_as_str.c_ptr(), field_name,
- (ulong) table->in_use->row_count);
+ table->in_use->warning_info.current_row_for_warning());
DBUG_RETURN(err);
}
@@ -2622,7 +2622,7 @@ int Field_new_decimal::store(const char
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"decimal", from_as_str.c_ptr(), field_name,
- (ulong) table->in_use->row_count);
+ table->in_use->warning_info.current_row_for_warning());
my_decimal_set_zero(&decimal_value);
break;
@@ -2659,7 +2659,7 @@ int Field_new_decimal::store(double nr)
if (check_overflow(err))
set_value_on_overflow(&decimal_value, decimal_value.sign());
/* Only issue a warning if store_value doesn't issue an warning */
- table->in_use->got_warning= 0;
+ table->in_use->got_warning= FALSE;
}
if (store_value(&decimal_value))
err= 1;
@@ -2681,7 +2681,7 @@ int Field_new_decimal::store(longlong nr
if (check_overflow(err))
set_value_on_overflow(&decimal_value, decimal_value.sign());
/* Only issue a warning if store_value doesn't issue an warning */
- table->in_use->got_warning= 0;
+ table->in_use->got_warning= FALSE;
}
if (store_value(&decimal_value))
err= 1;
@@ -5168,7 +5168,7 @@ bool Field_time::get_date(MYSQL_TIME *lt
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
ER(ER_WARN_DATA_OUT_OF_RANGE), field_name,
- thd->row_count);
+ thd->warning_info.current_row_for_warning());
return 1;
}
tmp=(long) sint3korr(ptr);
@@ -6158,6 +6158,7 @@ check_string_copy_error(Field_str *field
{
const char *pos, *end_orig;
char tmp[64], *t;
+ THD *thd= field->table->in_use;
if (!(pos= well_formed_error_pos) &&
!(pos= cannot_convert_error_pos))
@@ -6198,12 +6199,12 @@ check_string_copy_error(Field_str *field
*t++= '.';
}
*t= '\0';
- push_warning_printf(field->table->in_use,
+ push_warning_printf(thd,
MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"string", tmp, field->field_name,
- (ulong) field->table->in_use->row_count);
+ thd->warning_info.current_row_for_warning());
return TRUE;
}
@@ -10107,7 +10108,7 @@ Field::set_warning(MYSQL_ERROR::enum_war
{
thd->cuted_fields+= cuted_increment;
push_warning_printf(thd, level, code, ER(code), field_name,
- thd->row_count);
+ thd->warning_info.current_row_for_warning());
return 0;
}
return level >= MYSQL_ERROR::WARN_LEVEL_WARN;
=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc 2008-07-14 12:49:19 +0000
+++ b/sql/ha_ndbcluster_binlog.cc 2008-11-14 20:45:00 +0000
@@ -1899,7 +1899,7 @@ ndb_binlog_thread_handle_schema_event(TH
"my_errno: %d",
schema->db, schema->name, schema->query,
schema->node_id, my_errno);
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
MYSQL_ERROR *err;
while ((err= it++))
sql_print_warning("NDB Binlog: (%d)%s", err->code, err->msg);
@@ -2259,7 +2259,7 @@ ndb_binlog_thread_handle_schema_event_po
"binlog schema event '%s' from node %d. my_errno: %d",
schema->db, schema->name, schema->query,
schema->node_id, my_errno);
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
MYSQL_ERROR *err;
while ((err= it++))
sql_print_warning("NDB Binlog: (%d)%s", err->code, err->msg);
@@ -2438,7 +2438,7 @@ ndb_binlog_thread_handle_schema_event_po
"binlog schema event '%s' from node %d. my_errno: %d",
schema->db, schema->name, schema->query,
schema->node_id, my_errno);
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
MYSQL_ERROR *err;
while ((err= it++))
sql_print_warning("NDB Binlog: (%d)%s", err->code, err->msg);
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2008-11-06 18:46:03 +0000
+++ b/sql/handler.cc 2008-11-14 20:45:00 +0000
@@ -1862,20 +1862,20 @@ const char *get_canonical_filename(handl
struct Ha_delete_table_error_handler: public Internal_error_handler
{
public:
- virtual bool handle_error(uint sql_errno,
- const char *message,
+ virtual bool handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd);
+ uint sql_errno,
+ const char *message);
char buff[MYSQL_ERRMSG_SIZE];
};
bool
Ha_delete_table_error_handler::
-handle_error(uint sql_errno,
- const char *message,
+handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd)
+ uint sql_errno,
+ const char *message)
{
/* Grab the error message */
strmake(buff, message, sizeof(buff)-1);
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2008-11-06 18:39:27 +0000
+++ b/sql/log.cc 2008-11-14 20:45:00 +0000
@@ -83,17 +83,18 @@ public:
virtual ~Silence_log_table_errors() {}
- virtual bool handle_error(uint sql_errno, const char *message,
+ virtual bool handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd);
+ uint sql_errno, const char *message);
const char *message() const { return m_message; }
};
bool
-Silence_log_table_errors::handle_error(uint /* sql_errno */,
- const char *message_arg,
- MYSQL_ERROR::enum_warning_level /* level */,
- THD * /* thd */)
+Silence_log_table_errors::
+handle_error(THD * /* thd */,
+ MYSQL_ERROR::enum_warning_level /* level */,
+ uint /* sql_errno */,
+ const char *message_arg)
{
strmake(m_message, message_arg, sizeof(m_message)-1);
return TRUE;
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2008-11-06 18:46:03 +0000
+++ b/sql/log_event.cc 2008-11-14 20:45:00 +0000
@@ -133,7 +133,7 @@ static void inline slave_rows_error_repo
char buff[MAX_SLAVE_ERRMSG], *slider;
const char *buff_end= buff + sizeof(buff);
uint len;
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
MYSQL_ERROR *err;
buff[0]= 0;
@@ -4369,13 +4369,7 @@ int Load_log_event::do_apply_event(NET*
pthread_mutex_lock(&LOCK_thread_count);
thd->query_id = next_query_id();
pthread_mutex_unlock(&LOCK_thread_count);
- /*
- Initing thd->row_count is not necessary in theory as this variable has no
- influence in the case of the slave SQL thread (it is used to generate a
- "data truncated" warning but which is absorbed and never gets to the
- error log); still we init it to avoid a Valgrind message.
- */
- mysql_reset_errors(thd, 0);
+ thd->warning_info.opt_clear_warning_info(thd->query_id);
TABLE_LIST tables;
bzero((char*) &tables,sizeof(tables));
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2008-11-10 09:53:30 +0000
+++ b/sql/mysqld.cc 2008-11-14 20:45:00 +0000
@@ -3022,7 +3022,7 @@ void my_message_sql(uint error, const ch
TODO: There are two exceptions mechanism (THD and sp_rcontext),
this could be improved by having a common stack of handlers.
*/
- if (thd->handle_error(error, str, level))
+ if (thd->handle_error(level, error, str))
DBUG_VOID_RETURN;
if (level == MYSQL_ERROR::WARN_LEVEL_WARN)
@@ -3060,7 +3060,7 @@ void my_message_sql(uint error, const ch
*/
if (!thd->is_fatal_error && thd->spcont &&
! (MyFlags & ME_NO_SP_HANDLER) &&
- thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
+ thd->spcont->handle_error(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error))
{
/*
Do not push any warnings, a handled error must be completely
=== modified file 'sql/protocol.cc'
--- a/sql/protocol.cc 2008-10-20 09:16:47 +0000
+++ b/sql/protocol.cc 2008-11-14 20:45:00 +0000
@@ -31,10 +31,10 @@ static const unsigned int PACKET_BUFFER_
/* Declared non-static only because of the embedded library. */
void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
void net_send_ok(THD *, uint, uint, ha_rows, ulonglong, const char *);
-void net_send_eof(THD *thd, uint server_status, uint total_warn_count);
+void net_send_eof(THD *thd, uint server_status, uint statement_warn_count);
#ifndef EMBEDDED_LIBRARY
static void write_eof_packet(THD *thd, NET *net,
- uint server_status, uint total_warn_count);
+ uint server_status, uint statement_warn_count);
#endif
#ifndef EMBEDDED_LIBRARY
@@ -178,7 +178,7 @@ void net_send_error(THD *thd, uint sql_e
#ifndef EMBEDDED_LIBRARY
void
net_send_ok(THD *thd,
- uint server_status, uint total_warn_count,
+ uint server_status, uint statement_warn_count,
ha_rows affected_rows, ulonglong id, const char *message)
{
NET *net= &thd->net;
@@ -201,12 +201,12 @@ net_send_ok(THD *thd,
(ulong) affected_rows,
(ulong) id,
(uint) (server_status & 0xffff),
- (uint) total_warn_count));
+ (uint) statement_warn_count));
int2store(pos, server_status);
pos+=2;
/* We can only return up to 65535 warnings in two bytes */
- uint tmp= min(total_warn_count, 65535);
+ uint tmp= min(statement_warn_count, 65535);
int2store(pos, tmp);
pos+= 2;
}
@@ -250,7 +250,7 @@ static uchar eof_buff[1]= { (uchar) 254
*/
void
-net_send_eof(THD *thd, uint server_status, uint total_warn_count)
+net_send_eof(THD *thd, uint server_status, uint statement_warn_count)
{
NET *net= &thd->net;
DBUG_ENTER("net_send_eof");
@@ -258,7 +258,7 @@ net_send_eof(THD *thd, uint server_statu
if (net->vio != 0)
{
thd->main_da.can_overwrite_status= TRUE;
- write_eof_packet(thd, net, server_status, total_warn_count);
+ write_eof_packet(thd, net, server_status, statement_warn_count);
(void) net_flush(net);
thd->main_da.can_overwrite_status= FALSE;
DBUG_PRINT("info", ("EOF sent, so no more error sending allowed"));
@@ -274,7 +274,7 @@ net_send_eof(THD *thd, uint server_statu
static void write_eof_packet(THD *thd, NET *net,
uint server_status,
- uint total_warn_count)
+ uint statement_warn_count)
{
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
@@ -283,7 +283,7 @@ static void write_eof_packet(THD *thd, N
Don't send warn count during SP execution, as the warn_list
is cleared between substatements, and mysqltest gets confused
*/
- uint tmp= min(total_warn_count, 65535);
+ uint tmp= min(statement_warn_count, 65535);
buff[0]= 254;
int2store(buff+1, tmp);
/*
@@ -450,12 +450,12 @@ void net_end_statement(THD *thd)
case Diagnostics_area::DA_EOF:
net_send_eof(thd,
thd->main_da.server_status(),
- thd->main_da.total_warn_count());
+ thd->main_da.statement_warn_count());
break;
case Diagnostics_area::DA_OK:
net_send_ok(thd,
thd->main_da.server_status(),
- thd->main_da.total_warn_count(),
+ thd->main_da.statement_warn_count(),
thd->main_da.affected_rows(),
thd->main_da.last_insert_id(),
thd->main_da.message());
@@ -465,8 +465,7 @@ void net_end_statement(THD *thd)
case Diagnostics_area::DA_EMPTY:
default:
DBUG_ASSERT(0);
- net_send_ok(thd, thd->server_status, thd->total_warn_count,
- 0, 0, NULL);
+ net_send_ok(thd, thd->server_status, 0, 0, 0, NULL);
break;
}
thd->main_da.is_sent= TRUE;
@@ -702,7 +701,8 @@ bool Protocol::send_result_set_metadata(
to show that there is no cursor.
Send no warning information, as it will be sent at statement end.
*/
- write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
+ write_eof_packet(thd, &thd->net, thd->server_status,
+ thd->warning_info.statement_warn_count());
}
DBUG_RETURN(prepare_for_send(list->elements));
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2008-11-07 14:01:59 +0000
+++ b/sql/set_var.cc 2008-11-14 20:45:00 +0000
@@ -3434,17 +3434,14 @@ static int check_pseudo_thread_id(THD *t
static uchar *get_warning_count(THD *thd)
{
- thd->sys_var_tmp.long_value=
- (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
- thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
- thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
+ thd->sys_var_tmp.long_value= thd->warning_info.warn_count();
+
return (uchar*) &thd->sys_var_tmp.long_value;
}
static uchar *get_error_count(THD *thd)
{
- thd->sys_var_tmp.long_value=
- thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
+ thd->sys_var_tmp.long_value= thd->warning_info.error_count();
return (uchar*) &thd->sys_var_tmp.long_value;
}
=== modified file 'sql/slave.cc'
--- a/sql/slave.cc 2008-11-06 18:39:27 +0000
+++ b/sql/slave.cc 2008-11-14 20:45:00 +0000
@@ -1670,7 +1670,7 @@ static int has_temporary_error(THD *thd)
/*
currently temporary error set in ndbcluster
*/
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
MYSQL_ERROR *err;
while ((err= it++))
{
@@ -2610,7 +2610,7 @@ Slave SQL thread aborted. Can't execute
}
/* Print any warnings issued */
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
MYSQL_ERROR *err;
/*
Added controlled slave thread cancel for replication
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2008-07-15 16:29:51 +0000
+++ b/sql/sp.cc 2008-11-14 20:45:00 +0000
@@ -496,15 +496,15 @@ db_find_routine(THD *thd, int type, sp_n
struct Silence_deprecated_warning : public Internal_error_handler
{
public:
- virtual bool handle_error(uint sql_errno, const char *message,
+ virtual bool handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd);
+ uint sql_errno, const char *message);
};
bool
-Silence_deprecated_warning::handle_error(uint sql_errno, const char *message,
- MYSQL_ERROR::enum_warning_level level,
- THD *thd)
+Silence_deprecated_warning::
+handle_error(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ uint sql_errno, const char *message)
{
if (sql_errno == ER_WARN_DEPRECATED_SYNTAX &&
level == MYSQL_ERROR::WARN_LEVEL_WARN)
@@ -1329,7 +1329,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *
&thd->sp_proc_cache, FALSE) != NULL ||
sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
&thd->sp_func_cache, FALSE) != NULL;
- mysql_reset_errors(thd, TRUE);
+ thd->warning_info.clear_warning_info(thd->query_id);
if (sp_object_found)
{
if (any)
=== modified file 'sql/sp_rcontext.cc'
--- a/sql/sp_rcontext.cc 2008-08-15 17:31:50 +0000
+++ b/sql/sp_rcontext.cc 2008-11-14 20:45:00 +0000
@@ -293,9 +293,8 @@ sp_rcontext::find_handler(THD *thd, uint
FALSE if no handler was found.
*/
bool
-sp_rcontext::handle_error(uint sql_errno,
- MYSQL_ERROR::enum_warning_level level,
- THD *thd)
+sp_rcontext::handle_error(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ uint sql_errno)
{
MYSQL_ERROR::enum_warning_level elevated_level= level;
=== modified file 'sql/sp_rcontext.h'
--- a/sql/sp_rcontext.h 2008-08-15 17:31:50 +0000
+++ b/sql/sp_rcontext.h 2008-11-14 20:45:00 +0000
@@ -116,9 +116,8 @@ class sp_rcontext : public Sql_alloc
// If there is an error handler for this error, handle it and return TRUE.
bool
- handle_error(uint sql_errno,
- MYSQL_ERROR::enum_warning_level level,
- THD *thd);
+ handle_error(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ uint sql_errno);
// Returns handler type and sets *ip to location if one was found
inline int
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2008-10-20 19:13:22 +0000
+++ b/sql/sql_acl.cc 2008-11-14 20:45:00 +0000
@@ -6144,9 +6144,9 @@ public:
virtual ~Silence_routine_definer_errors()
{}
- virtual bool handle_error(uint sql_errno, const char *message,
+ virtual bool handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd);
+ uint sql_errno, const char *message);
bool has_errors() { return is_grave; }
@@ -6155,10 +6155,9 @@ private:
};
bool
-Silence_routine_definer_errors::handle_error(uint sql_errno,
- const char *message,
- MYSQL_ERROR::enum_warning_level level,
- THD *thd)
+Silence_routine_definer_errors::
+handle_error(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ uint sql_errno, const char *message)
{
if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
{
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2008-11-06 18:39:27 +0000
+++ b/sql/sql_base.cc 2008-11-14 20:45:00 +0000
@@ -45,9 +45,9 @@ public:
virtual ~Prelock_error_handler() {}
- virtual bool handle_error(uint sql_errno, const char *message,
+ virtual bool handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd);
+ uint sql_errno, const char *message);
bool safely_trapped_errors();
@@ -58,10 +58,10 @@ private:
bool
-Prelock_error_handler::handle_error(uint sql_errno,
- const char * /* message */,
+Prelock_error_handler::handle_error(THD * /* thd */,
MYSQL_ERROR::enum_warning_level /* level */,
- THD * /* thd */)
+ uint sql_errno,
+ const char * /* message */)
{
if (sql_errno == ER_NO_SUCH_TABLE)
{
@@ -602,7 +602,7 @@ static TABLE_SHARE
DBUG_RETURN(0);
}
/* Table existed in engine. Let's open it */
- mysql_reset_errors(thd, 1); // Clear warnings
+ thd->warning_info.clear_warning_info(thd->query_id);
thd->clear_error(); // Clear error message
DBUG_RETURN(get_table_share(thd, table_list, key, key_length,
db_flags, error));
@@ -3483,7 +3483,7 @@ recover_from_failed_open_table_attempt(T
ha_create_table_from_engine(thd, table->db, table->table_name);
pthread_mutex_unlock(&LOCK_open);
- mysql_reset_errors(thd, 1); // Clear warnings
+ thd->warning_info.clear_warning_info(thd->query_id);
thd->clear_error(); // Clear error message
mdl_release_lock(&thd->mdl_context, table->mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, table->mdl_lock_data);
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2008-11-07 14:04:18 +0000
+++ b/sql/sql_class.cc 2008-11-14 20:45:00 +0000
@@ -304,7 +304,7 @@ int thd_tx_isolation(const THD *thd)
extern "C"
void thd_inc_row_count(THD *thd)
{
- thd->row_count++;
+ thd->warning_info.inc_current_row_for_warning();
}
@@ -407,7 +407,7 @@ Diagnostics_area::reset_diagnostics_area
m_server_status= 0;
m_affected_rows= 0;
m_last_insert_id= 0;
- m_total_warn_count= 0;
+ m_statement_warn_count= 0;
#endif
is_sent= FALSE;
/** Tiny reset in debug mode to see garbage right away */
@@ -436,7 +436,7 @@ Diagnostics_area::set_ok_status(THD *thd
return;
m_server_status= thd->server_status;
- m_total_warn_count= thd->total_warn_count;
+ m_statement_warn_count= thd->warning_info.statement_warn_count();
m_affected_rows= affected_rows_arg;
m_last_insert_id= last_insert_id_arg;
if (message_arg)
@@ -471,7 +471,8 @@ Diagnostics_area::set_eof_status(THD *th
number of warnings, since they are not available to the client
anyway.
*/
- m_total_warn_count= thd->spcont ? 0 : thd->total_warn_count;
+ m_statement_warn_count= (thd->spcont ?
+ 0 : thd->warning_info.statement_warn_count());
m_status= DA_EOF;
DBUG_VOID_RETURN;
@@ -525,6 +526,59 @@ Diagnostics_area::disable_status()
}
+Warning_info::Warning_info(query_id_t warn_id_arg)
+ :m_statement_warn_count(0),
+ m_current_row_for_warning(1),
+ m_warn_id(warn_id_arg)
+{
+ /* Initialize sub structures */
+ init_sql_alloc(&m_warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
+ m_warn_list.empty();
+ bzero((char*) m_warn_count, sizeof(m_warn_count));
+}
+
+
+Warning_info::~Warning_info()
+{
+ free_root(&m_warn_root,MYF(0));
+}
+
+
+/**
+ Reset the warning information of this connection.
+*/
+
+void Warning_info::clear_warning_info(query_id_t warn_id_arg)
+{
+ m_warn_id= warn_id_arg;
+ free_root(&m_warn_root, MYF(0));
+ bzero((char*) m_warn_count, sizeof(m_warn_count));
+ m_warn_list.empty();
+ m_statement_warn_count= 0;
+ m_current_row_for_warning= 1; /* Start counting from the first row */
+}
+
+
+/**
+ Add a warning to the list of warnings. Increment the respective
+ counters.
+*/
+
+void Warning_info::push_warning(THD *thd,
+ MYSQL_ERROR::enum_warning_level level,
+ uint code, const char *msg)
+{
+ if (m_warn_list.elements < thd->variables.max_error_count)
+ {
+ MYSQL_ERROR *err;
+ if ((err= new (&m_warn_root) MYSQL_ERROR(&m_warn_root, level, code, msg)))
+ m_warn_list.push_back(err, &m_warn_root);
+ }
+ m_warn_count[(uint) level]++;
+ m_statement_warn_count++;
+}
+
+
THD::THD()
:Statement(&main_lex, &main_mem_root, CONVENTIONAL_EXECUTION,
/* statement id */ 0),
@@ -538,6 +592,7 @@ THD::THD()
first_successful_insert_id_in_prev_stmt_for_binlog(0),
first_successful_insert_id_in_cur_stmt(0),
stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
+ warning_info(0),
global_read_lock(0),
is_fatal_error(0),
transaction_rollback_request(0),
@@ -584,7 +639,8 @@ THD::THD()
hash_clear(&handler_tables_hash);
tmp_table=0;
used_tables=0;
- cuted_fields= sent_row_count= row_count= 0L;
+ cuted_fields= 0L;
+ sent_row_count= 0L;
limit_found_rows= 0;
row_count_func= -1;
statement_id_counter= 0UL;
@@ -603,7 +659,6 @@ THD::THD()
one_shot_set= 0;
file_id = 0;
query_id= 0;
- warn_id= 0;
db_charset= global_system_variables.collation_database;
bzero(ha_data, sizeof(ha_data));
mysys_var=0;
@@ -644,8 +699,6 @@ THD::THD()
init_open_tables_state(this, refresh_version);
init();
- /* Initialize sub structures */
- init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
#if defined(ENABLED_PROFILING)
profiling.set_thd(this);
#endif
@@ -691,13 +744,11 @@ void THD::push_internal_handler(Internal
}
-bool THD::handle_error(uint sql_errno, const char *message,
- MYSQL_ERROR::enum_warning_level level)
+bool THD::handle_error(MYSQL_ERROR::enum_warning_level level,
+ uint sql_errno, const char *message)
{
if (m_internal_handler)
- {
- return m_internal_handler->handle_error(sql_errno, message, level, this);
- }
+ return m_internal_handler->handle_error(this, level, sql_errno, message);
return FALSE; // 'FALSE', as per coding style
}
@@ -791,9 +842,6 @@ void THD::init(void)
TL_WRITE_LOW_PRIORITY :
TL_WRITE);
session_tx_isolation= (enum_tx_isolation) variables.tx_isolation;
- warn_list.empty();
- bzero((char*) warn_count, sizeof(warn_count));
- total_warn_count= 0;
update_charset();
reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var));
@@ -962,7 +1010,6 @@ THD::~THD()
DBUG_PRINT("info", ("freeing security context"));
main_security_ctx.destroy();
safeFree(db);
- free_root(&warn_root,MYF(0));
free_root(&transaction.mem_root,MYF(0));
mysys_var=0; // Safety (shouldn't be needed)
pthread_mutex_destroy(&LOCK_delete);
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2008-11-06 18:39:27 +0000
+++ b/sql/sql_class.h 2008-11-14 20:45:00 +0000
@@ -1133,10 +1133,10 @@ public:
@param thd the calling thread
@return true if the error is handled
*/
- virtual bool handle_error(uint sql_errno,
- const char *message,
+ virtual bool handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd) = 0;
+ uint sql_errno,
+ const char *message) = 0;
};
@@ -1203,10 +1203,10 @@ public:
ulonglong last_insert_id() const
{ DBUG_ASSERT(m_status == DA_OK); return m_last_insert_id; }
- uint total_warn_count() const
+ uint statement_warn_count() const
{
DBUG_ASSERT(m_status == DA_OK || m_status == DA_EOF);
- return m_total_warn_count;
+ return m_statement_warn_count;
}
Diagnostics_area() { reset_diagnostics_area(); }
@@ -1247,8 +1247,13 @@ private:
to implement LAST_INSERT_ID().
*/
ulonglong m_last_insert_id;
- /** The total number of warnings. */
- uint m_total_warn_count;
+ /**
+ Number of warnings of this last statement. May differ from
+ the number of warnings returned by SHOW WARNINGS e.g. in case
+ the statement doesn't clear the warnings, and doesn't generate
+ them.
+ */
+ uint m_statement_warn_count;
enum_diagnostics_status m_status;
/**
@todo: the following THD members belong here:
@@ -1256,6 +1261,120 @@ private:
*/
};
+
+/**
+ Information about warnings of the current connection.
+*/
+
+class Warning_info
+{
+ /** A memory root to allocate warnings and errors */
+ MEM_ROOT m_warn_root;
+ /** List of warnings of all severities (levels). */
+ List <MYSQL_ERROR> m_warn_list;
+ /** A break down of the number of warnings per severity (level). */
+ uint m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
+ /**
+ The number of warnings of the current statement. Warning_info
+ life cycle differs from statement life cycle -- it may span
+ multiple statements. In that case we get
+ m_statement_warn_count 0, whereas m_warn_list is not empty.
+ */
+ uint m_statement_warn_count;
+ /*
+ Row counter, to print in errors and warnings. Not increased in
+ create_sort_index(); may differ from examined_row_count.
+ */
+ ulong m_current_row_for_warning;
+ /** Used to optionally clear warnings only once per statement. */
+ query_id_t m_warn_id;
+
+private:
+ Warning_info(const Warning_info &rhs); /* Not implemented */
+ Warning_info& operator=(const Warning_info &rhs); /* Not implemented */
+public:
+
+ Warning_info(query_id_t warn_id_arg);
+ /* Do nothing - used to initialize a backup info */
+ Warning_info() { clear_alloc_root(&m_warn_root); }
+ ~Warning_info();
+
+ /**
+ Reset the warning information. Clear all warnings,
+ the number of warnings, reset current row counter
+ to point to the first row.
+ */
+ void clear_warning_info(query_id_t warn_id_arg);
+ /**
+ Only clear warning info if haven't yet done that already
+ for the current query. Allows to be issued at any time
+ during the query, without risk of clearing some warnings
+ that have been generated by the current statement.
+
+ @todo: This is a sign of sloppy coding. Instead we need to
+ designate one place in a statement life cycle where we call
+ clear_warning_info().
+ */
+ void opt_clear_warning_info(query_id_t query_id)
+ {
+ if (query_id != m_warn_id)
+ clear_warning_info(query_id);
+ }
+
+ /**
+ Reset between two COM_ commands. Warnings are preserved
+ between commands, but statement_warn_count indicates
+ the number of warnings of this particular statement only.
+ */
+ void reset_for_next_command() { m_statement_warn_count= 0; }
+
+ /**
+ Used for @@warning_count system variable, which prints
+ the number of rows returned by SHOW WARNINGS.
+ */
+ ulong warn_count() const
+ {
+ /*
+ This may be higher than warn_list.elements if we have
+ had more warnings than thd->variables.max_error_count.
+ */
+ return (m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
+ m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
+ m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
+ }
+
+ /**
+ This is for iteration purposes. We return a non-constant reference
+ since List doesn't have constant iterators.
+ */
+ List<MYSQL_ERROR> &warn_list() { return m_warn_list; }
+
+ /**
+ The number of errors, or number of rows returned by SHOW ERRORS,
+ also the value of session variable @@error_count.
+ */
+ ulong error_count() const
+ {
+ return m_warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
+ }
+
+ /** Do we have any errors and warnings that we can *show*? */
+ bool is_empty() const { return m_warn_list.elements == 0; }
+
+ /** Increment the current row counter to point at the next row. */
+ void inc_current_row_for_warning() { m_current_row_for_warning++; }
+ /** Reset the current row counter. Start counting from the first row. */
+ void reset_current_row_for_warning() { m_current_row_for_warning= 1; }
+ /** Return the current counter value. */
+ ulong current_row_for_warning() const { return m_current_row_for_warning; }
+
+ ulong statement_warn_count() const { return m_statement_warn_count; }
+
+ /** Add a new warning to the current list. */
+ void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
+ uint code, const char *msg);
+};
+
/**
Tables that were locked with LOCK TABLES statement.
@@ -1380,7 +1499,6 @@ public:
Query_cache_tls query_cache_tls;
#endif
NET net; // client connection descriptor
- MEM_ROOT warn_root; // For warnings and errors
Protocol *protocol; // Current protocol
Protocol_text protocol_text; // Normal protocol
Protocol_binary protocol_binary; // Binary protocol
@@ -1786,15 +1904,7 @@ public:
table_map used_tables;
USER_CONN *user_connect;
CHARSET_INFO *db_charset;
- /*
- FIXME: this, and some other variables like 'count_cuted_fields'
- maybe should be statement/cursor local, that is, moved to Statement
- class. With current implementation warnings produced in each prepared
- statement/cursor settle here.
- */
- List <MYSQL_ERROR> warn_list;
- uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
- uint total_warn_count;
+ Warning_info warning_info;
Diagnostics_area main_da;
#if defined(ENABLED_PROFILING)
PROFILING profiling;
@@ -1808,7 +1918,7 @@ public:
from table are necessary for this select, to check if it's necessary to
update auto-updatable fields (like auto_increment and timestamp).
*/
- query_id_t query_id, warn_id;
+ query_id_t query_id;
ulong col_access;
#ifdef ERROR_INJECT_SUPPORT
@@ -1817,11 +1927,6 @@ public:
/* Statement id is thread-wide. This counter is used to generate ids */
ulong statement_id_counter;
ulong rand_saved_seed1, rand_saved_seed2;
- /*
- Row counter, mainly for errors and warnings. Not increased in
- create_sort_index(); may differ from examined_row_count.
- */
- ulong row_count;
pthread_t real_id; /* For debugging */
my_thread_id thread_id;
uint tmp_table, global_read_lock;
@@ -2393,8 +2498,8 @@ public:
@param level the error level
@return true if the error is handled
*/
- virtual bool handle_error(uint sql_errno, const char *message,
- MYSQL_ERROR::enum_warning_level level);
+ virtual bool handle_error(MYSQL_ERROR::enum_warning_level level,
+ uint sql_errno, const char *message);
/**
Remove the error handler last pushed.
=== modified file 'sql/sql_error.cc'
--- a/sql/sql_error.cc 2008-10-08 15:37:32 +0000
+++ b/sql/sql_error.cc 2008-11-14 20:45:00 +0000
@@ -44,51 +44,15 @@ This file contains the implementation of
#include "mysql_priv.h"
#include "sp_rcontext.h"
-/*
- Store a new message in an error object
-
- This is used to in group_concat() to register how many warnings we actually
- got after the query has been executed.
-*/
+/* Store a new message in an error object. */
-void MYSQL_ERROR::set_msg(THD *thd, const char *msg_arg)
+void MYSQL_ERROR::set_msg(MEM_ROOT *warn_root, const char *msg_arg)
{
- msg= strdup_root(&thd->warn_root, msg_arg);
+ msg= strdup_root(warn_root, msg_arg);
}
/*
- Reset all warnings for the thread
-
- SYNOPSIS
- mysql_reset_errors()
- thd Thread handle
- force Reset warnings even if it has been done before
-
- IMPLEMENTATION
- Don't reset warnings if this has already been called for this query.
- This may happen if one gets a warning during the parsing stage,
- in which case push_warnings() has already called this function.
-*/
-
-void mysql_reset_errors(THD *thd, bool force)
-{
- DBUG_ENTER("mysql_reset_errors");
- if (thd->query_id != thd->warn_id || force)
- {
- thd->warn_id= thd->query_id;
- free_root(&thd->warn_root,MYF(0));
- bzero((char*) thd->warn_count, sizeof(thd->warn_count));
- if (force)
- thd->total_warn_count= 0;
- thd->warn_list.empty();
- thd->row_count= 1; // by default point to row 1
- }
- DBUG_VOID_RETURN;
-}
-
-
-/*
Push the warning/error to error list if there is still room in the list
SYNOPSIS
@@ -102,7 +66,6 @@ void mysql_reset_errors(THD *thd, bool f
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *msg)
{
- MYSQL_ERROR *err= 0;
DBUG_ENTER("push_warning");
DBUG_PRINT("enter", ("code: %d, msg: %s", code, msg));
@@ -113,8 +76,9 @@ void push_warning(THD *thd, MYSQL_ERROR:
!(thd->options & OPTION_SQL_NOTES))
DBUG_VOID_RETURN;
- if (thd->query_id != thd->warn_id && !thd->spcont)
- mysql_reset_errors(thd, 0);
+ if (! thd->spcont)
+ thd->warning_info.opt_clear_warning_info(thd->query_id);
+
thd->got_warning= 1;
/* Abort if we are using strict mode and we are not using IGNORE */
@@ -137,25 +101,18 @@ void push_warning(THD *thd, MYSQL_ERROR:
level= MYSQL_ERROR::WARN_LEVEL_ERROR;
}
- if (thd->handle_error(code, msg, level))
+ if (thd->handle_error(level, code, msg))
DBUG_VOID_RETURN;
if (thd->spcont &&
- thd->spcont->handle_error(code, level, thd))
+ thd->spcont->handle_error(thd, level, code))
{
DBUG_VOID_RETURN;
}
query_cache_abort(&thd->query_cache_tls);
+ thd->warning_info.push_warning(thd, level, code, msg);
- if (thd->warn_list.elements < thd->variables.max_error_count)
- {
- /* We have to use warn_root, as mem_root is freed after each query */
- if ((err= new (&thd->warn_root) MYSQL_ERROR(thd, code, level, msg)))
- thd->warn_list.push_back(err, &thd->warn_root);
- }
- thd->warn_count[(uint) level]++;
- thd->total_warn_count++;
DBUG_VOID_RETURN;
}
@@ -234,7 +191,7 @@ bool mysqld_show_warnings(THD *thd, ulon
unit->set_limit(sel);
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
while ((err= it++))
{
/* Skip levels that the user is not interested in */
=== modified file 'sql/sql_error.h'
--- a/sql/sql_error.h 2008-07-29 22:03:57 +0000
+++ b/sql/sql_error.h 2008-11-14 20:45:00 +0000
@@ -19,27 +19,26 @@ public:
enum enum_warning_level
{ WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
- uint code;
enum_warning_level level;
+ uint code;
char *msg;
-
- MYSQL_ERROR(THD *thd, uint code_arg, enum_warning_level level_arg,
- const char *msg_arg)
- :code(code_arg), level(level_arg)
+
+ MYSQL_ERROR(MEM_ROOT *warn_root,
+ enum_warning_level level_arg, uint code_arg, const char *msg_arg)
+ :level(level_arg), code(code_arg)
{
if (msg_arg)
- set_msg(thd, msg_arg);
+ set_msg(warn_root, msg_arg);
}
private:
- void set_msg(THD *thd, const char *msg_arg);
+ void set_msg(MEM_ROOT *warn_root, const char *msg_arg);
};
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *msg);
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
uint code, const char *format, ...);
-void mysql_reset_errors(THD *thd, bool force);
bool mysqld_show_warnings(THD *thd, ulong levels_to_show);
extern const LEX_STRING warning_level_names[];
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2008-11-06 18:39:27 +0000
+++ b/sql/sql_insert.cc 2008-11-14 20:45:00 +0000
@@ -835,7 +835,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
error=write_record(thd, table ,&info);
if (error)
break;
- thd->row_count++;
+ thd->warning_info.inc_current_row_for_warning();
}
free_underlaid_joins(thd, &thd->lex->select_lex);
=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc 2008-09-17 16:14:21 +0000
+++ b/sql/sql_load.cc 2008-11-14 20:45:00 +0000
@@ -644,7 +644,8 @@ read_fixed_length(THD *thd, COPY_INFO &i
thd->cuted_fields++; /* Not enough fields */
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_TOO_FEW_RECORDS,
- ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
+ ER(ER_WARN_TOO_FEW_RECORDS),
+ thd->warning_info.current_row_for_warning());
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
((Field_timestamp*) field)->set_time();
}
@@ -667,7 +668,8 @@ read_fixed_length(THD *thd, COPY_INFO &i
thd->cuted_fields++; /* To long row */
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_TOO_MANY_RECORDS,
- ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
+ ER(ER_WARN_TOO_MANY_RECORDS),
+ thd->warning_info.current_row_for_warning());
}
if (thd->killed ||
@@ -702,9 +704,10 @@ read_fixed_length(THD *thd, COPY_INFO &i
thd->cuted_fields++; /* To long row */
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_TOO_MANY_RECORDS,
- ER(ER_WARN_TOO_MANY_RECORDS), thd->row_count);
+ ER(ER_WARN_TOO_MANY_RECORDS),
+ thd->warning_info.current_row_for_warning());
}
- thd->row_count++;
+ thd->warning_info.inc_current_row_for_warning();
continue_loop:;
}
DBUG_RETURN(test(read_info.error));
@@ -768,7 +771,7 @@ read_sep_field(THD *thd, COPY_INFO &info
if (field->reset())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name,
- thd->row_count);
+ thd->warning_info.current_row_for_warning());
DBUG_RETURN(1);
}
field->set_null();
@@ -836,7 +839,7 @@ read_sep_field(THD *thd, COPY_INFO &info
if (field->reset())
{
my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name,
- thd->row_count);
+ thd->warning_info.current_row_for_warning());
DBUG_RETURN(1);
}
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
@@ -850,7 +853,8 @@ read_sep_field(THD *thd, COPY_INFO &info
thd->cuted_fields++;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_TOO_FEW_RECORDS,
- ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
+ ER(ER_WARN_TOO_FEW_RECORDS),
+ thd->warning_info.current_row_for_warning());
}
else if (item->type() == Item::STRING_ITEM)
{
@@ -896,11 +900,11 @@ read_sep_field(THD *thd, COPY_INFO &info
thd->cuted_fields++; /* To long row */
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_TOO_MANY_RECORDS, ER(ER_WARN_TOO_MANY_RECORDS),
- thd->row_count);
+ thd->warning_info.current_row_for_warning());
if (thd->killed)
DBUG_RETURN(1);
}
- thd->row_count++;
+ thd->warning_info.inc_current_row_for_warning();
continue_loop:;
}
DBUG_RETURN(test(read_info.error));
@@ -1033,7 +1037,8 @@ read_xml_field(THD *thd, COPY_INFO &info
thd->cuted_fields++;
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_TOO_FEW_RECORDS,
- ER(ER_WARN_TOO_FEW_RECORDS), thd->row_count);
+ ER(ER_WARN_TOO_FEW_RECORDS),
+ thd->warning_info.current_row_for_warning());
}
else
((Item_user_var_as_out_param *)item)->set_null_value(cs);
@@ -1064,7 +1069,7 @@ read_xml_field(THD *thd, COPY_INFO &info
its default value at the beginning of each loop iteration.
*/
thd->transaction.stmt.modified_non_trans_table= no_trans_update_stmt;
- thd->row_count++;
+ thd->warning_info.inc_current_row_for_warning();
continue_loop:;
}
DBUG_RETURN(test(read_info.error));
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2008-11-06 18:39:27 +0000
+++ b/sql/sql_parse.cc 2008-11-14 20:45:00 +0000
@@ -1412,7 +1412,7 @@ bool dispatch_command(enum enum_server_c
0,0,0,0,
thd->query,thd->query_length,
thd->variables.character_set_client,
- thd->row_count);
+ thd->warning_info.current_row_for_warning());
}
log_slow_statement(thd);
@@ -1851,7 +1851,7 @@ mysql_execute_command(THD *thd)
Don't reset warnings when executing a stored routine.
*/
if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont)
- mysql_reset_errors(thd, 0);
+ thd->warning_info.opt_clear_warning_info(thd->query_id);
#ifdef HAVE_REPLICATION
if (unlikely(thd->slave_thread))
@@ -4126,12 +4126,6 @@ create_sp_error:
So just execute the statement.
*/
res= sp->execute_procedure(thd, &lex->value_list);
- /*
- If warnings have been cleared, we have to clear total_warn_count
- too, otherwise the clients get confused.
- */
- if (thd->warn_list.is_empty())
- thd->total_warn_count= 0;
thd->variables.select_limit= select_limit;
@@ -4162,7 +4156,7 @@ create_sp_error:
else
sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
&thd->sp_func_cache, FALSE);
- mysql_reset_errors(thd, 0);
+ thd->warning_info.opt_clear_warning_info(thd->query_id);
if (! sp)
{
if (lex->spname->m_db.str)
@@ -4282,7 +4276,7 @@ create_sp_error:
}
sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
- mysql_reset_errors(thd, 0);
+ thd->warning_info.opt_clear_warning_info(thd->query_id);
if (sp_result == SP_OK)
{
char *db= lex->spname->m_db.str;
@@ -5373,7 +5367,7 @@ void mysql_reset_thd_for_next_command(TH
}
thd->clear_error();
thd->main_da.reset_diagnostics_area();
- thd->total_warn_count=0; // Warnings for this query
+ thd->warning_info.reset_for_next_command();
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
thd->thd_marker.emb_on_expr_nest= NULL;
=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc 2008-11-06 18:39:27 +0000
+++ b/sql/sql_prepare.cc 2008-11-14 20:45:00 +0000
@@ -248,7 +248,7 @@ static bool send_prep_stmt(Prepared_stat
int2store(buff+5, columns);
int2store(buff+7, stmt->param_count);
buff[9]= 0; // Guard against a 4.1 client
- tmp= min(stmt->thd->total_warn_count, 65535);
+ tmp= min(stmt->thd->warning_info.statement_warn_count(), 65535);
int2store(buff+10, tmp);
/*
@@ -1839,7 +1839,7 @@ static bool check_prepared_statement(Pre
/* Reset warning count for each query that uses tables */
if ((tables || !lex->is_single_level_stmt()) && !thd->spcont)
- mysql_reset_errors(thd, 0);
+ thd->warning_info.opt_clear_warning_info(thd->query_id);
switch (sql_command) {
case SQLCOM_REPLACE:
@@ -3293,12 +3293,12 @@ Prepared_statement::reprepare()
#endif
/*
Clear possible warnings during reprepare, it has to be completely
- transparent to the user. We use mysql_reset_errors() since
+ transparent to the user. We use mysql_reset_warnings() since
there were no separate query id issued for re-prepare.
Sic: we can't simply silence warnings during reprepare, because if
it's failed, we need to return all the warnings to the user.
*/
- mysql_reset_errors(thd, TRUE);
+ thd->warning_info.clear_warning_info(thd->query_id);
}
return error;
}
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2008-11-06 18:39:27 +0000
+++ b/sql/sql_select.cc 2008-11-14 20:45:00 +0000
@@ -13454,7 +13454,6 @@ do_select(JOIN *join,List<Item> *fields,
so we don't touch it here.
*/
join->examined_rows++;
- join->thd->row_count++;
DBUG_ASSERT(join->examined_rows <= 1);
}
else if (join->send_row_on_empty_set())
@@ -13718,7 +13717,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
/* Set first_unmatched for the last inner table of this group */
join_tab->last_inner->first_unmatched= join_tab;
}
- join->thd->row_count= 0;
+ join->thd->warning_info.reset_current_row_for_warning();
error= (*join_tab->read_first_record)(join_tab);
rc= evaluate_join_record(join, join_tab, error);
@@ -13962,7 +13961,6 @@ evaluate_join_record(JOIN *join, JOIN_TA
(See above join->return_tab= tab).
*/
join->examined_rows++;
- join->thd->row_count++;
DBUG_PRINT("counts", ("join->examined_rows++: %lu",
(ulong) join->examined_rows));
@@ -13971,6 +13969,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
enum enum_nested_loop_state rc;
/* A match from join_tab is found for the current partial join. */
rc= (*join_tab->next_select)(join, join_tab+1, 0);
+ join->thd->warning_info.inc_current_row_for_warning();
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
return rc;
if (return_tab < join->return_tab)
@@ -13987,7 +13986,10 @@ evaluate_join_record(JOIN *join, JOIN_TA
return NESTED_LOOP_NO_MORE_ROWS;
}
else
+ {
+ join->thd->warning_info.inc_current_row_for_warning();
join_tab->read_record.file->unlock_row();
+ }
}
else
{
@@ -13996,7 +13998,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
with the beginning coinciding with the current partial join.
*/
join->examined_rows++;
- join->thd->row_count++;
+ join->thd->warning_info.inc_current_row_for_warning();
join_tab->read_record.file->unlock_row();
}
return NESTED_LOOP_OK;
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2008-11-06 18:39:27 +0000
+++ b/sql/sql_show.cc 2008-11-14 20:45:00 +0000
@@ -516,7 +516,7 @@ mysqld_show_create(THD *thd, TABLE_LIST
issue a warning with 'warning' level status in
case of invalid view and last error is ER_VIEW_INVALID
*/
- mysql_reset_errors(thd, true);
+ thd->warning_info.clear_warning_info(thd->query_id);
thd->clear_error();
push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-11-06 18:39:27 +0000
+++ b/sql/sql_table.cc 2008-11-14 20:45:00 +0000
@@ -4289,7 +4289,7 @@ static bool mysql_admin_table(THD* thd,
if (!table->table)
{
DBUG_PRINT("admin", ("open table failed"));
- if (!thd->warn_list.elements)
+ if (thd->warning_info.is_empty())
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
/* if it was a view will check md5 sum */
@@ -4397,7 +4397,7 @@ send_result:
lex->cleanup_after_one_table_open();
thd->clear_error(); // these errors shouldn't get client
{
- List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+ List_iterator_fast<MYSQL_ERROR> it(thd->warning_info.warn_list());
MYSQL_ERROR *err;
while ((err= it++))
{
@@ -4411,7 +4411,7 @@ send_result:
if (protocol->write())
goto err;
}
- mysql_reset_errors(thd, true);
+ thd->warning_info.clear_warning_info(thd->query_id);
}
protocol->prepare_for_resend();
protocol->store(table_name, system_charset_info);
@@ -7236,7 +7236,8 @@ err:
the table to be altered isn't empty.
Report error here.
*/
- if (alter_info->error_if_not_empty && thd->row_count)
+ if (alter_info->error_if_not_empty &&
+ thd->warning_info.current_row_for_warning())
{
const char *f_val= 0;
enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
@@ -7408,7 +7409,7 @@ copy_data_between_tables(TABLE *from,TAB
errpos= 4;
if (ignore)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- thd->row_count= 0;
+ thd->warning_info.reset_current_row_for_warning();
restore_record(to, s->default_values); // Create empty record
while (!(error=info.read_record(&info)))
{
@@ -7418,7 +7419,6 @@ copy_data_between_tables(TABLE *from,TAB
error= 1;
break;
}
- thd->row_count++;
/* Return error if source table isn't empty. */
if (error_if_not_empty)
{
@@ -7468,6 +7468,7 @@ copy_data_between_tables(TABLE *from,TAB
}
else
found_count++;
+ thd->warning_info.inc_current_row_for_warning();
}
err:
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2008-10-20 19:13:22 +0000
+++ b/sql/sql_update.cc 2008-11-14 20:45:00 +0000
@@ -727,7 +727,7 @@ int mysql_update(THD *thd,
}
else
table->file->unlock_row();
- thd->row_count++;
+ thd->warning_info.inc_current_row_for_warning();
}
dup_key_found= 0;
/*
=== modified file 'sql/time.cc'
--- a/sql/time.cc 2008-02-13 19:27:12 +0000
+++ b/sql/time.cc 2008-11-14 20:45:00 +0000
@@ -748,7 +748,7 @@ void make_truncated_value_warning(THD *t
cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
type_str, str.c_ptr(), field_name,
- (ulong) thd->row_count);
+ (ulong) thd->warning_info.current_row_for_warning());
else
{
if (time_type > MYSQL_TIMESTAMP_ERROR)
=== modified file 'sql/unireg.cc'
--- a/sql/unireg.cc 2008-11-04 08:10:49 +0000
+++ b/sql/unireg.cc 2008-11-14 20:45:00 +0000
@@ -56,10 +56,10 @@ static bool make_empty_rec(THD *thd, int
struct Pack_header_error_handler: public Internal_error_handler
{
- virtual bool handle_error(uint sql_errno,
- const char *message,
+ virtual bool handle_error(THD *thd,
MYSQL_ERROR::enum_warning_level level,
- THD *thd);
+ uint sql_errno,
+ const char *message);
bool is_handled;
Pack_header_error_handler() :is_handled(FALSE) {}
};
@@ -67,10 +67,10 @@ struct Pack_header_error_handler: public
bool
Pack_header_error_handler::
-handle_error(uint sql_errno,
- const char * /* message */,
+handle_error(THD * /* thd */,
MYSQL_ERROR::enum_warning_level /* level */,
- THD * /* thd */)
+ uint sql_errno,
+ const char * /* message */)
{
is_handled= (sql_errno == ER_TOO_MANY_FIELDS);
return is_handled;
| Thread |
|---|
| • bzr push into mysql-6.0-runtime branch (kostja:2744 to 2745) WL#4264 | Konstantin Osipov | 14 Nov |