1
/* Copyright (C) 1995-2002 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/**********************************************************************
17
This file contains the implementation of error and warnings related
19
- Whenever an error or warning occurred, it pushes it to a warning list
20
that the user can retrieve with SHOW WARNINGS or SHOW ERRORS.
22
- For each statement, we return the number of warnings generated from this
23
command. Note that this can be different from @@warning_count as
24
we reset the warning list only for questions that uses a table.
25
This is done to allow on to do:
27
SELECT @@warning_count;
29
(If we would reset after each command, we could not retrieve the number
32
- When client requests the information using SHOW command, then
33
server processes from this list and returns back in the form of
38
SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows]
39
SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows]
40
SELECT @@warning_count, @@error_count;
42
***********************************************************************/
44
#include <drizzled/server_includes.h>
47
Store a new message in an error object
49
This is used to in group_concat() to register how many warnings we actually
50
got after the query has been executed.
52
void DRIZZLE_ERROR::set_msg(Session *session, const char *msg_arg)
54
msg= strdup_root(&session->warn_root, msg_arg);
58
Reset all warnings for the thread
61
drizzle_reset_errors()
63
force Reset warnings even if it has been done before
66
Don't reset warnings if this has already been called for this query.
67
This may happen if one gets a warning during the parsing stage,
68
in which case push_warnings() has already called this function.
71
void drizzle_reset_errors(Session *session, bool force)
73
if (session->query_id != session->warn_id || force)
75
session->warn_id= session->query_id;
76
free_root(&session->warn_root,MYF(0));
77
memset(session->warn_count, 0, sizeof(session->warn_count));
79
session->total_warn_count= 0;
80
session->warn_list.empty();
81
session->row_count= 1; // by default point to row 1
88
Push the warning/error to error list if there is still room in the list
93
level Severity of warning (note, warning, error ...)
95
msg Clear error message
98
pointer on DRIZZLE_ERROR object
101
DRIZZLE_ERROR *push_warning(Session *session, DRIZZLE_ERROR::enum_warning_level level,
102
uint32_t code, const char *msg)
104
DRIZZLE_ERROR *err= 0;
106
if (level == DRIZZLE_ERROR::WARN_LEVEL_NOTE &&
107
!(session->options & OPTION_SQL_NOTES))
110
if (session->query_id != session->warn_id)
111
drizzle_reset_errors(session, 0);
112
session->got_warning= 1;
114
/* Abort if we are using strict mode and we are not using IGNORE */
115
if ((int) level >= (int) DRIZZLE_ERROR::WARN_LEVEL_WARN &&
116
session->really_abort_on_warning())
118
/* Avoid my_message() calling push_warning */
119
bool no_warnings_for_error= session->no_warnings_for_error;
121
session->no_warnings_for_error= 1;
123
session->killed= Session::KILL_BAD_DATA;
124
my_message(code, msg, MYF(0));
126
session->no_warnings_for_error= no_warnings_for_error;
127
/* Store error in error list (as my_message() didn't do it) */
128
level= DRIZZLE_ERROR::WARN_LEVEL_ERROR;
131
if (session->handle_error(code, msg, level))
134
if (session->warn_list.elements < session->variables.max_error_count)
136
/* We have to use warn_root, as mem_root is freed after each query */
137
if ((err= new (&session->warn_root) DRIZZLE_ERROR(session, code, level, msg)))
138
session->warn_list.push_back(err, &session->warn_root);
140
session->warn_count[(uint) level]++;
141
session->total_warn_count++;
146
Push the warning/error to error list if there is still room in the list
149
push_warning_printf()
150
session Thread handle
151
level Severity of warning (note, warning, error ...)
153
msg Clear error message
156
void push_warning_printf(Session *session, DRIZZLE_ERROR::enum_warning_level level,
157
uint32_t code, const char *format, ...)
160
char warning[ERRMSGSIZE+20];
162
va_start(args,format);
163
vsnprintf(warning, sizeof(warning), format, args);
165
push_warning(session, level, code, warning);
171
Send all notes, errors or warnings to the client in a result set
174
mysqld_show_warnings()
175
session Thread handler
176
levels_to_show Bitmap for which levels to show
179
Takes into account the current LIMIT
183
true Error sending data to client
186
const LEX_STRING warning_level_names[]=
188
{ C_STRING_WITH_LEN("Note") },
189
{ C_STRING_WITH_LEN("Warning") },
190
{ C_STRING_WITH_LEN("Error") },
191
{ C_STRING_WITH_LEN("?") }
194
bool mysqld_show_warnings(Session *session, uint32_t levels_to_show)
196
List<Item> field_list;
198
field_list.push_back(new Item_empty_string("Level", 7));
199
field_list.push_back(new Item_return_int("Code",4, DRIZZLE_TYPE_LONG));
200
field_list.push_back(new Item_empty_string("Message",DRIZZLE_ERRMSG_SIZE));
202
if (session->protocol->send_fields(&field_list,
203
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
207
SELECT_LEX *sel= &session->lex->select_lex;
208
SELECT_LEX_UNIT *unit= &session->lex->unit;
210
Protocol *protocol=session->protocol;
212
unit->set_limit(sel);
214
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
217
/* Skip levels that the user is not interested in */
218
if (!(levels_to_show & ((ulong) 1 << err->level)))
220
if (++idx <= unit->offset_limit_cnt)
222
if (idx > unit->select_limit_cnt)
224
protocol->prepare_for_resend();
225
protocol->store(warning_level_names[err->level].str,
226
warning_level_names[err->level].length, system_charset_info);
227
protocol->store((uint32_t) err->code);
228
protocol->store(err->msg, strlen(err->msg), system_charset_info);
229
if (protocol->write())