~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_error.cc

  • Committer: Moriyoshi Koizumi
  • Date: 2008-11-15 18:36:31 UTC
  • mto: (584.1.5 devel)
  • mto: This revision was merged to the branch mainline in revision 588.
  • Revision ID: mozo@mozo.jp-20081115183631-81d0clowyot42mk7
Incorporating changes proposed by mtaylor.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
15
15
 
16
16
/**********************************************************************
17
17
This file contains the implementation of error and warnings related
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 <drizzled/server_includes.h>
59
45
 
60
46
/*
61
47
  Store a new message in an error object
65
51
*/
66
52
void DRIZZLE_ERROR::set_msg(Session *session, const char *msg_arg)
67
53
{
68
 
  msg= session->warn_root.strdup_root(msg_arg);
 
54
  msg= strdup_root(&session->warn_root, msg_arg);
69
55
}
70
56
 
71
57
/*
80
66
    Don't reset warnings if this has already been called for this query.
81
67
    This may happen if one gets a warning during the parsing stage,
82
68
    in which case push_warnings() has already called this function.
83
 
*/
 
69
*/  
84
70
 
85
71
void drizzle_reset_errors(Session *session, bool force)
86
72
{
87
 
  if (session->getQueryId() != session->getWarningQueryId() || force)
 
73
  if (session->query_id != session->warn_id || force)
88
74
  {
89
 
    session->setWarningQueryId(session->getQueryId());
90
 
    session->warn_root.free_root(MYF(0));
 
75
    session->warn_id= session->query_id;
 
76
    free_root(&session->warn_root,MYF(0));
91
77
    memset(session->warn_count, 0, sizeof(session->warn_count));
92
78
    if (force)
93
79
      session->total_warn_count= 0;
94
 
    session->warn_list.clear();
 
80
    session->warn_list.empty();
95
81
    session->row_count= 1; // by default point to row 1
96
82
  }
97
83
  return;
98
84
}
99
85
 
100
86
 
101
 
/*
 
87
/* 
102
88
  Push the warning/error to error list if there is still room in the list
103
89
 
104
90
  SYNOPSIS
107
93
    level               Severity of warning (note, warning, error ...)
108
94
    code                Error number
109
95
    msg                 Clear error message
110
 
 
 
96
    
111
97
  RETURN
112
98
    pointer on DRIZZLE_ERROR object
113
99
*/
114
100
 
115
 
DRIZZLE_ERROR *push_warning(Session *session, DRIZZLE_ERROR::enum_warning_level level,
116
 
                            drizzled::error_t code, const char *msg)
 
101
DRIZZLE_ERROR *push_warning(Session *session, DRIZZLE_ERROR::enum_warning_level level, 
 
102
                          uint32_t code, const char *msg)
117
103
{
118
104
  DRIZZLE_ERROR *err= 0;
119
105
 
120
 
  if (level == DRIZZLE_ERROR::WARN_LEVEL_NOTE && !(session->options & OPTION_SQL_NOTES))
121
 
  {
122
 
    return NULL;
123
 
  }
 
106
  if (level == DRIZZLE_ERROR::WARN_LEVEL_NOTE &&
 
107
      !(session->options & OPTION_SQL_NOTES))
 
108
    return(0);
124
109
 
125
 
  if (session->getQueryId() != session->getWarningQueryId())
 
110
  if (session->query_id != session->warn_id)
126
111
    drizzle_reset_errors(session, 0);
127
112
  session->got_warning= 1;
128
113
 
129
114
  /* Abort if we are using strict mode and we are not using IGNORE */
130
115
  if ((int) level >= (int) DRIZZLE_ERROR::WARN_LEVEL_WARN &&
131
 
      session->abortOnWarning())
 
116
      session->really_abort_on_warning())
132
117
  {
133
118
    /* Avoid my_message() calling push_warning */
134
119
    bool no_warnings_for_error= session->no_warnings_for_error;
135
120
 
136
121
    session->no_warnings_for_error= 1;
137
122
 
138
 
    session->setKilled(Session::KILL_BAD_DATA);
 
123
    session->killed= Session::KILL_BAD_DATA;
139
124
    my_message(code, msg, MYF(0));
140
125
 
141
126
    session->no_warnings_for_error= no_warnings_for_error;
144
129
  }
145
130
 
146
131
  if (session->handle_error(code, msg, level))
147
 
    return NULL;
 
132
    return(NULL);
148
133
 
149
134
  if (session->warn_list.elements < session->variables.max_error_count)
150
135
  {
151
136
    /* We have to use warn_root, as mem_root is freed after each query */
152
137
    if ((err= new (&session->warn_root) DRIZZLE_ERROR(session, code, level, msg)))
153
 
    {
154
138
      session->warn_list.push_back(err, &session->warn_root);
155
 
    }
156
139
  }
157
 
  session->warn_count[(uint32_t) level]++;
 
140
  session->warn_count[(uint) level]++;
158
141
  session->total_warn_count++;
159
 
 
160
 
  return err;
 
142
  return(err);
161
143
}
162
144
 
163
145
/*
172
154
*/
173
155
 
174
156
void push_warning_printf(Session *session, DRIZZLE_ERROR::enum_warning_level level,
175
 
                         drizzled::error_t code, const char *format, ...)
 
157
                         uint32_t code, const char *format, ...)
176
158
{
177
159
  va_list args;
178
160
  char    warning[ERRMSGSIZE+20];
179
 
 
 
161
  
180
162
  va_start(args,format);
181
163
  vsnprintf(warning, sizeof(warning), format, args);
182
164
  va_end(args);
183
165
  push_warning(session, level, code, warning);
 
166
  return;
184
167
}
185
168
 
186
169
 
188
171
  Send all notes, errors or warnings to the client in a result set
189
172
 
190
173
  SYNOPSIS
191
 
    show_warnings()
 
174
    mysqld_show_warnings()
192
175
    session                     Thread handler
193
176
    levels_to_show      Bitmap for which levels to show
194
177
 
208
191
  { C_STRING_WITH_LEN("?") }
209
192
};
210
193
 
211
 
bool show_warnings(Session *session,
212
 
                   bitset<DRIZZLE_ERROR::NUM_ERRORS> &levels_to_show)
213
 
{
 
194
bool mysqld_show_warnings(Session *session, uint32_t levels_to_show)
 
195
{  
214
196
  List<Item> field_list;
215
197
 
216
198
  field_list.push_back(new Item_empty_string("Level", 7));
217
199
  field_list.push_back(new Item_return_int("Code",4, DRIZZLE_TYPE_LONG));
218
200
  field_list.push_back(new Item_empty_string("Message",DRIZZLE_ERRMSG_SIZE));
219
201
 
220
 
  if (session->getClient()->sendFields(&field_list))
221
 
    return true;
 
202
  if (session->protocol->send_fields(&field_list,
 
203
                                 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
204
    return(true);
222
205
 
223
206
  DRIZZLE_ERROR *err;
224
 
  Select_Lex *sel= &session->getLex()->select_lex;
225
 
  Select_Lex_Unit *unit= &session->getLex()->unit;
 
207
  SELECT_LEX *sel= &session->lex->select_lex;
 
208
  SELECT_LEX_UNIT *unit= &session->lex->unit;
226
209
  ha_rows idx= 0;
 
210
  Protocol *protocol=session->protocol;
227
211
 
228
212
  unit->set_limit(sel);
229
213
 
230
 
  List<DRIZZLE_ERROR>::iterator it(session->warn_list.begin());
 
214
  List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
231
215
  while ((err= it++))
232
216
  {
233
217
    /* Skip levels that the user is not interested in */
234
 
    if (! levels_to_show.test(err->level))
 
218
    if (!(levels_to_show & ((ulong) 1 << err->level)))
235
219
      continue;
236
220
    if (++idx <= unit->offset_limit_cnt)
237
221
      continue;
238
222
    if (idx > unit->select_limit_cnt)
239
223
      break;
240
 
    session->getClient()->store(warning_level_names[err->level].str,
241
 
                                warning_level_names[err->level].length);
242
 
    session->getClient()->store((uint32_t) err->code);
243
 
    session->getClient()->store(err->msg, strlen(err->msg));
244
 
    if (session->getClient()->flush())
 
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())
245
230
      return(true);
246
231
  }
247
 
  session->my_eof();
 
232
  my_eof(session);
248
233
  return(false);
249
234
}
250
 
 
251
 
} /* namespace drizzled */