~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/sql_error.cc

  • Committer: Brian Aker
  • Date: 2008-07-03 00:14:39 UTC
  • Revision ID: brian@tangent.org-20080703001439-pit0mcl0wk8elxlq
Cleanup of sql-common and mysqldump

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
    (If we would reset after each command, we could not retrieve the number
30
30
     of warnings)
31
31
 
32
 
  - When client requests the information using SHOW command, then
33
 
    server processes from this list and returns back in the form of
 
32
  - When client requests the information using SHOW command, then 
 
33
    server processes from this list and returns back in the form of 
34
34
    resultset.
35
35
 
36
36
    Supported syntaxes:
41
41
 
42
42
***********************************************************************/
43
43
 
44
 
#include "config.h"
45
 
 
46
 
#include <cstdio>
47
 
#include <stdarg.h>
48
 
 
49
 
#include <drizzled/session.h>
50
 
#include <drizzled/sql_base.h>
51
 
#include <drizzled/item/empty_string.h>
52
 
#include <drizzled/item/return_int.h>
53
 
#include <drizzled/plugin/client.h>
54
 
 
55
 
using namespace std;
56
 
 
57
 
namespace drizzled
58
 
{
 
44
#include "mysql_priv.h"
59
45
 
60
46
/*
61
47
  Store a new message in an error object
63
49
  This is used to in group_concat() to register how many warnings we actually
64
50
  got after the query has been executed.
65
51
*/
66
 
void DRIZZLE_ERROR::set_msg(Session *session, const char *msg_arg)
 
52
 
 
53
void MYSQL_ERROR::set_msg(THD *thd, const char *msg_arg)
67
54
{
68
 
  msg= session->warn_root.strdup_root(msg_arg);
 
55
  msg= strdup_root(&thd->warn_root, msg_arg);
69
56
}
70
57
 
 
58
 
71
59
/*
72
60
  Reset all warnings for the thread
73
61
 
74
62
  SYNOPSIS
75
 
    drizzle_reset_errors()
76
 
    session                     Thread handle
 
63
    mysql_reset_errors()
 
64
    thd                 Thread handle
77
65
    force               Reset warnings even if it has been done before
78
66
 
79
67
  IMPLEMENTATION
80
68
    Don't reset warnings if this has already been called for this query.
81
69
    This may happen if one gets a warning during the parsing stage,
82
70
    in which case push_warnings() has already called this function.
83
 
*/
 
71
*/  
84
72
 
85
 
void drizzle_reset_errors(Session *session, bool force)
 
73
void mysql_reset_errors(THD *thd, bool force)
86
74
{
87
 
  if (session->getQueryId() != session->getWarningQueryId() || force)
 
75
  DBUG_ENTER("mysql_reset_errors");
 
76
  if (thd->query_id != thd->warn_id || force)
88
77
  {
89
 
    session->setWarningQueryId(session->getQueryId());
90
 
    session->warn_root.free_root(MYF(0));
91
 
    memset(session->warn_count, 0, sizeof(session->warn_count));
 
78
    thd->warn_id= thd->query_id;
 
79
    free_root(&thd->warn_root,MYF(0));
 
80
    bzero((char*) thd->warn_count, sizeof(thd->warn_count));
92
81
    if (force)
93
 
      session->total_warn_count= 0;
94
 
    session->warn_list.empty();
95
 
    session->row_count= 1; // by default point to row 1
 
82
      thd->total_warn_count= 0;
 
83
    thd->warn_list.empty();
 
84
    thd->row_count= 1; // by default point to row 1
96
85
  }
97
 
  return;
 
86
  DBUG_VOID_RETURN;
98
87
}
99
88
 
100
89
 
101
 
/*
 
90
/* 
102
91
  Push the warning/error to error list if there is still room in the list
103
92
 
104
93
  SYNOPSIS
105
94
    push_warning()
106
 
    session                     Thread handle
 
95
    thd                 Thread handle
107
96
    level               Severity of warning (note, warning, error ...)
108
97
    code                Error number
109
98
    msg                 Clear error message
110
 
 
 
99
    
111
100
  RETURN
112
 
    pointer on DRIZZLE_ERROR object
 
101
    pointer on MYSQL_ERROR object
113
102
*/
114
103
 
115
 
DRIZZLE_ERROR *push_warning(Session *session, DRIZZLE_ERROR::enum_warning_level level,
116
 
                          uint32_t code, const char *msg)
 
104
MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, 
 
105
                          uint code, const char *msg)
117
106
{
118
 
  DRIZZLE_ERROR *err= 0;
119
 
 
120
 
  if (level == DRIZZLE_ERROR::WARN_LEVEL_NOTE &&
121
 
      !(session->options & OPTION_SQL_NOTES))
122
 
    return(0);
123
 
 
124
 
  if (session->getQueryId() != session->getWarningQueryId())
125
 
    drizzle_reset_errors(session, 0);
126
 
  session->got_warning= 1;
 
107
  MYSQL_ERROR *err= 0;
 
108
  DBUG_ENTER("push_warning");
 
109
  DBUG_PRINT("enter", ("code: %d, msg: %s", code, msg));
 
110
 
 
111
  if (level == MYSQL_ERROR::WARN_LEVEL_NOTE &&
 
112
      !(thd->options & OPTION_SQL_NOTES))
 
113
    DBUG_RETURN(0);
 
114
 
 
115
  if (thd->query_id != thd->warn_id)
 
116
    mysql_reset_errors(thd, 0);
 
117
  thd->got_warning= 1;
127
118
 
128
119
  /* Abort if we are using strict mode and we are not using IGNORE */
129
 
  if ((int) level >= (int) DRIZZLE_ERROR::WARN_LEVEL_WARN &&
130
 
      session->really_abort_on_warning())
 
120
  if ((int) level >= (int) MYSQL_ERROR::WARN_LEVEL_WARN &&
 
121
      thd->really_abort_on_warning())
131
122
  {
132
123
    /* Avoid my_message() calling push_warning */
133
 
    bool no_warnings_for_error= session->no_warnings_for_error;
134
 
 
135
 
    session->no_warnings_for_error= 1;
136
 
 
137
 
    session->killed= Session::KILL_BAD_DATA;
 
124
    bool no_warnings_for_error= thd->no_warnings_for_error;
 
125
 
 
126
    thd->no_warnings_for_error= 1;
 
127
 
 
128
    thd->killed= THD::KILL_BAD_DATA;
138
129
    my_message(code, msg, MYF(0));
139
130
 
140
 
    session->no_warnings_for_error= no_warnings_for_error;
 
131
    thd->no_warnings_for_error= no_warnings_for_error;
141
132
    /* Store error in error list (as my_message() didn't do it) */
142
 
    level= DRIZZLE_ERROR::WARN_LEVEL_ERROR;
 
133
    level= MYSQL_ERROR::WARN_LEVEL_ERROR;
143
134
  }
144
135
 
145
 
  if (session->handle_error(code, msg, level))
146
 
    return NULL;
 
136
  if (thd->handle_error(code, msg, level))
 
137
    DBUG_RETURN(NULL);
147
138
 
148
 
  if (session->warn_list.elements < session->variables.max_error_count)
 
139
  if (thd->warn_list.elements < thd->variables.max_error_count)
149
140
  {
150
141
    /* We have to use warn_root, as mem_root is freed after each query */
151
 
    if ((err= new (&session->warn_root) DRIZZLE_ERROR(session, code, level, msg)))
152
 
      session->warn_list.push_back(err, &session->warn_root);
 
142
    if ((err= new (&thd->warn_root) MYSQL_ERROR(thd, code, level, msg)))
 
143
      thd->warn_list.push_back(err, &thd->warn_root);
153
144
  }
154
 
  session->warn_count[(uint32_t) level]++;
155
 
  session->total_warn_count++;
156
 
  return(err);
 
145
  thd->warn_count[(uint) level]++;
 
146
  thd->total_warn_count++;
 
147
  DBUG_RETURN(err);
157
148
}
158
149
 
159
150
/*
161
152
 
162
153
  SYNOPSIS
163
154
    push_warning_printf()
164
 
    session                     Thread handle
 
155
    thd                 Thread handle
165
156
    level               Severity of warning (note, warning, error ...)
166
157
    code                Error number
167
158
    msg                 Clear error message
168
159
*/
169
160
 
170
 
void push_warning_printf(Session *session, DRIZZLE_ERROR::enum_warning_level level,
171
 
                         uint32_t code, const char *format, ...)
 
161
void push_warning_printf(THD *thd, MYSQL_ERROR::enum_warning_level level,
 
162
                         uint code, const char *format, ...)
172
163
{
173
164
  va_list args;
174
165
  char    warning[ERRMSGSIZE+20];
175
 
 
 
166
  DBUG_ENTER("push_warning_printf");
 
167
  DBUG_PRINT("enter",("warning: %u", code));
 
168
  
176
169
  va_start(args,format);
177
 
  vsnprintf(warning, sizeof(warning), format, args);
 
170
  my_vsnprintf(warning, sizeof(warning), format, args);
178
171
  va_end(args);
179
 
  push_warning(session, level, code, warning);
180
 
  return;
 
172
  push_warning(thd, level, code, warning);
 
173
  DBUG_VOID_RETURN;
181
174
}
182
175
 
183
176
 
186
179
 
187
180
  SYNOPSIS
188
181
    mysqld_show_warnings()
189
 
    session                     Thread handler
 
182
    thd                 Thread handler
190
183
    levels_to_show      Bitmap for which levels to show
191
184
 
192
185
  DESCRIPTION
193
186
    Takes into account the current LIMIT
194
187
 
195
188
  RETURN VALUES
196
 
    false ok
197
 
    true  Error sending data to client
 
189
    FALSE ok
 
190
    TRUE  Error sending data to client
198
191
*/
199
192
 
200
193
const LEX_STRING warning_level_names[]=
205
198
  { C_STRING_WITH_LEN("?") }
206
199
};
207
200
 
208
 
bool mysqld_show_warnings(Session *session,
209
 
                          bitset<DRIZZLE_ERROR::NUM_ERRORS> &levels_to_show)
210
 
{
 
201
bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
 
202
{  
211
203
  List<Item> field_list;
 
204
  DBUG_ENTER("mysqld_show_warnings");
212
205
 
213
206
  field_list.push_back(new Item_empty_string("Level", 7));
214
 
  field_list.push_back(new Item_return_int("Code",4, DRIZZLE_TYPE_LONG));
215
 
  field_list.push_back(new Item_empty_string("Message",DRIZZLE_ERRMSG_SIZE));
216
 
 
217
 
  if (session->client->sendFields(&field_list))
218
 
    return true;
219
 
 
220
 
  DRIZZLE_ERROR *err;
221
 
  Select_Lex *sel= &session->lex->select_lex;
222
 
  Select_Lex_Unit *unit= &session->lex->unit;
 
207
  field_list.push_back(new Item_return_int("Code",4, MYSQL_TYPE_LONG));
 
208
  field_list.push_back(new Item_empty_string("Message",MYSQL_ERRMSG_SIZE));
 
209
 
 
210
  if (thd->protocol->send_fields(&field_list,
 
211
                                 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
212
    DBUG_RETURN(TRUE);
 
213
 
 
214
  MYSQL_ERROR *err;
 
215
  SELECT_LEX *sel= &thd->lex->select_lex;
 
216
  SELECT_LEX_UNIT *unit= &thd->lex->unit;
223
217
  ha_rows idx= 0;
 
218
  Protocol *protocol=thd->protocol;
224
219
 
225
220
  unit->set_limit(sel);
226
221
 
227
 
  List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
 
222
  List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
228
223
  while ((err= it++))
229
224
  {
230
225
    /* Skip levels that the user is not interested in */
231
 
    if (! levels_to_show.test(err->level))
 
226
    if (!(levels_to_show & ((ulong) 1 << err->level)))
232
227
      continue;
233
228
    if (++idx <= unit->offset_limit_cnt)
234
229
      continue;
235
230
    if (idx > unit->select_limit_cnt)
236
231
      break;
237
 
    session->client->store(warning_level_names[err->level].str,
238
 
                           warning_level_names[err->level].length);
239
 
    session->client->store((uint32_t) err->code);
240
 
    session->client->store(err->msg, strlen(err->msg));
241
 
    if (session->client->flush())
242
 
      return(true);
 
232
    protocol->prepare_for_resend();
 
233
    protocol->store(warning_level_names[err->level].str,
 
234
                    warning_level_names[err->level].length, system_charset_info);
 
235
    protocol->store((uint32) err->code);
 
236
    protocol->store(err->msg, strlen(err->msg), system_charset_info);
 
237
    if (protocol->write())
 
238
      DBUG_RETURN(TRUE);
243
239
  }
244
 
  session->my_eof();
245
 
  return(false);
 
240
  my_eof(thd);
 
241
  DBUG_RETURN(FALSE);
246
242
}
247
 
 
248
 
} /* namespace drizzled */