~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 1995-2002 MySQL AB
2
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.
6
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.
11
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 */
15
16
/**********************************************************************
17
This file contains the implementation of error and warnings related
18
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.
21
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:
26
    INSERT ...;
27
    SELECT @@warning_count;
28
    SHOW WARNINGS;
29
    (If we would reset after each command, we could not retrieve the number
30
     of warnings)
31
32
  - When client requests the information using SHOW command, then 
33
    server processes from this list and returns back in the form of 
34
    resultset.
35
36
    Supported syntaxes:
37
38
    SHOW [COUNT(*)] ERRORS [LIMIT [offset,] rows]
39
    SHOW [COUNT(*)] WARNINGS [LIMIT [offset,] rows]
40
    SELECT @@warning_count, @@error_count;
41
42
***********************************************************************/
43
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
44
#include <drizzled/server_includes.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
45
#include <drizzled/session.h>
46
#include <drizzled/sql_base.h>
1 by brian
clean slate
47
48
/*
49
  Store a new message in an error object
50
51
  This is used to in group_concat() to register how many warnings we actually
52
  got after the query has been executed.
53
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
54
void DRIZZLE_ERROR::set_msg(Session *session, const char *msg_arg)
1 by brian
clean slate
55
{
520.1.22 by Brian Aker
Second pass of thd cleanup
56
  msg= strdup_root(&session->warn_root, msg_arg);
1 by brian
clean slate
57
}
58
59
/*
60
  Reset all warnings for the thread
61
62
  SYNOPSIS
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
63
    drizzle_reset_errors()
520.1.22 by Brian Aker
Second pass of thd cleanup
64
    session			Thread handle
1 by brian
clean slate
65
    force               Reset warnings even if it has been done before
66
67
  IMPLEMENTATION
68
    Don't reset warnings if this has already been called for this query.
69
    This may happen if one gets a warning during the parsing stage,
70
    in which case push_warnings() has already called this function.
71
*/  
72
520.1.22 by Brian Aker
Second pass of thd cleanup
73
void drizzle_reset_errors(Session *session, bool force)
1 by brian
clean slate
74
{
520.1.22 by Brian Aker
Second pass of thd cleanup
75
  if (session->query_id != session->warn_id || force)
1 by brian
clean slate
76
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
77
    session->warn_id= session->query_id;
78
    free_root(&session->warn_root,MYF(0));
79
    memset(session->warn_count, 0, sizeof(session->warn_count));
1 by brian
clean slate
80
    if (force)
520.1.22 by Brian Aker
Second pass of thd cleanup
81
      session->total_warn_count= 0;
82
    session->warn_list.empty();
83
    session->row_count= 1; // by default point to row 1
1 by brian
clean slate
84
  }
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
85
  return;
1 by brian
clean slate
86
}
87
88
89
/* 
90
  Push the warning/error to error list if there is still room in the list
91
92
  SYNOPSIS
93
    push_warning()
520.1.22 by Brian Aker
Second pass of thd cleanup
94
    session			Thread handle
1 by brian
clean slate
95
    level		Severity of warning (note, warning, error ...)
96
    code		Error number
97
    msg			Clear error message
98
    
99
  RETURN
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
100
    pointer on DRIZZLE_ERROR object
1 by brian
clean slate
101
*/
102
520.1.22 by Brian Aker
Second pass of thd cleanup
103
DRIZZLE_ERROR *push_warning(Session *session, DRIZZLE_ERROR::enum_warning_level level, 
482 by Brian Aker
Remove uint.
104
                          uint32_t code, const char *msg)
1 by brian
clean slate
105
{
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
106
  DRIZZLE_ERROR *err= 0;
1 by brian
clean slate
107
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
108
  if (level == DRIZZLE_ERROR::WARN_LEVEL_NOTE &&
520.1.22 by Brian Aker
Second pass of thd cleanup
109
      !(session->options & OPTION_SQL_NOTES))
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
110
    return(0);
1 by brian
clean slate
111
520.1.22 by Brian Aker
Second pass of thd cleanup
112
  if (session->query_id != session->warn_id)
113
    drizzle_reset_errors(session, 0);
114
  session->got_warning= 1;
1 by brian
clean slate
115
116
  /* Abort if we are using strict mode and we are not using IGNORE */
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
117
  if ((int) level >= (int) DRIZZLE_ERROR::WARN_LEVEL_WARN &&
520.1.22 by Brian Aker
Second pass of thd cleanup
118
      session->really_abort_on_warning())
1 by brian
clean slate
119
  {
120
    /* Avoid my_message() calling push_warning */
520.1.22 by Brian Aker
Second pass of thd cleanup
121
    bool no_warnings_for_error= session->no_warnings_for_error;
122
123
    session->no_warnings_for_error= 1;
124
125
    session->killed= Session::KILL_BAD_DATA;
1 by brian
clean slate
126
    my_message(code, msg, MYF(0));
127
520.1.22 by Brian Aker
Second pass of thd cleanup
128
    session->no_warnings_for_error= no_warnings_for_error;
1 by brian
clean slate
129
    /* Store error in error list (as my_message() didn't do it) */
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
130
    level= DRIZZLE_ERROR::WARN_LEVEL_ERROR;
1 by brian
clean slate
131
  }
132
520.1.22 by Brian Aker
Second pass of thd cleanup
133
  if (session->handle_error(code, msg, level))
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
134
    return(NULL);
1 by brian
clean slate
135
520.1.22 by Brian Aker
Second pass of thd cleanup
136
  if (session->warn_list.elements < session->variables.max_error_count)
1 by brian
clean slate
137
  {
138
    /* We have to use warn_root, as mem_root is freed after each query */
520.1.22 by Brian Aker
Second pass of thd cleanup
139
    if ((err= new (&session->warn_root) DRIZZLE_ERROR(session, code, level, msg)))
140
      session->warn_list.push_back(err, &session->warn_root);
1 by brian
clean slate
141
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
142
  session->warn_count[(uint) level]++;
143
  session->total_warn_count++;
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
144
  return(err);
1 by brian
clean slate
145
}
146
147
/*
148
  Push the warning/error to error list if there is still room in the list
149
150
  SYNOPSIS
151
    push_warning_printf()
520.1.22 by Brian Aker
Second pass of thd cleanup
152
    session			Thread handle
1 by brian
clean slate
153
    level		Severity of warning (note, warning, error ...)
154
    code		Error number
155
    msg			Clear error message
156
*/
157
520.1.22 by Brian Aker
Second pass of thd cleanup
158
void push_warning_printf(Session *session, DRIZZLE_ERROR::enum_warning_level level,
482 by Brian Aker
Remove uint.
159
			 uint32_t code, const char *format, ...)
1 by brian
clean slate
160
{
161
  va_list args;
162
  char    warning[ERRMSGSIZE+20];
163
  
164
  va_start(args,format);
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
165
  vsnprintf(warning, sizeof(warning), format, args);
1 by brian
clean slate
166
  va_end(args);
520.1.22 by Brian Aker
Second pass of thd cleanup
167
  push_warning(session, level, code, warning);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
168
  return;
1 by brian
clean slate
169
}
170
171
172
/*
173
  Send all notes, errors or warnings to the client in a result set
174
175
  SYNOPSIS
176
    mysqld_show_warnings()
520.1.22 by Brian Aker
Second pass of thd cleanup
177
    session			Thread handler
1 by brian
clean slate
178
    levels_to_show	Bitmap for which levels to show
179
180
  DESCRIPTION
181
    Takes into account the current LIMIT
182
183
  RETURN VALUES
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
184
    false ok
185
    true  Error sending data to client
1 by brian
clean slate
186
*/
187
188
const LEX_STRING warning_level_names[]=
189
{
190
  { C_STRING_WITH_LEN("Note") },
191
  { C_STRING_WITH_LEN("Warning") },
192
  { C_STRING_WITH_LEN("Error") },
193
  { C_STRING_WITH_LEN("?") }
194
};
195
520.1.22 by Brian Aker
Second pass of thd cleanup
196
bool mysqld_show_warnings(Session *session, uint32_t levels_to_show)
1 by brian
clean slate
197
{  
198
  List<Item> field_list;
199
200
  field_list.push_back(new Item_empty_string("Level", 7));
212.2.2 by Patrick Galbraith
Renamed FIELD_TYPE to DRIZZLE_TYPE
201
  field_list.push_back(new Item_return_int("Code",4, DRIZZLE_TYPE_LONG));
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
202
  field_list.push_back(new Item_empty_string("Message",DRIZZLE_ERRMSG_SIZE));
1 by brian
clean slate
203
520.1.22 by Brian Aker
Second pass of thd cleanup
204
  if (session->protocol->send_fields(&field_list,
1 by brian
clean slate
205
                                 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
206
    return(true);
1 by brian
clean slate
207
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
208
  DRIZZLE_ERROR *err;
520.1.22 by Brian Aker
Second pass of thd cleanup
209
  SELECT_LEX *sel= &session->lex->select_lex;
210
  SELECT_LEX_UNIT *unit= &session->lex->unit;
1 by brian
clean slate
211
  ha_rows idx= 0;
520.1.22 by Brian Aker
Second pass of thd cleanup
212
  Protocol *protocol=session->protocol;
1 by brian
clean slate
213
214
  unit->set_limit(sel);
215
520.1.22 by Brian Aker
Second pass of thd cleanup
216
  List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
1 by brian
clean slate
217
  while ((err= it++))
218
  {
219
    /* Skip levels that the user is not interested in */
220
    if (!(levels_to_show & ((ulong) 1 << err->level)))
221
      continue;
222
    if (++idx <= unit->offset_limit_cnt)
223
      continue;
224
    if (idx > unit->select_limit_cnt)
225
      break;
226
    protocol->prepare_for_resend();
227
    protocol->store(warning_level_names[err->level].str,
228
		    warning_level_names[err->level].length, system_charset_info);
205 by Brian Aker
uint32 -> uin32_t
229
    protocol->store((uint32_t) err->code);
1 by brian
clean slate
230
    protocol->store(err->msg, strlen(err->msg), system_charset_info);
231
    if (protocol->write())
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
232
      return(true);
1 by brian
clean slate
233
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
234
  my_eof(session);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
235
  return(false);
1 by brian
clean slate
236
}