~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_error.cc

  • Committer: Jay Pipes
  • Date: 2008-09-11 16:03:22 UTC
  • mto: (383.5.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 386.
  • Revision ID: jay@mysql.com-20080911160322-vrl0k1djo6q6ytv1
Removed SQL_MODE variances from comment_table.test and ensured correct error thrown when a comment that is too long was input.  After moving to proto buffer definition for table, the 2048 length will go away.

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
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
void DRIZZLE_ERROR::set_msg(THD *thd, const char *msg_arg)
67
53
{
68
 
  msg= session->warn_root.strdup_root(msg_arg);
 
54
  msg= strdup_root(&thd->warn_root, msg_arg);
69
55
}
70
56
 
71
57
/*
73
59
 
74
60
  SYNOPSIS
75
61
    drizzle_reset_errors()
76
 
    session                     Thread handle
 
62
    thd                 Thread handle
77
63
    force               Reset warnings even if it has been done before
78
64
 
79
65
  IMPLEMENTATION
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
 
void drizzle_reset_errors(Session *session, bool force)
 
71
void drizzle_reset_errors(THD *thd, bool force)
86
72
{
87
 
  if (session->getQueryId() != session->getWarningQueryId() || force)
 
73
  if (thd->query_id != thd->warn_id || force)
88
74
  {
89
 
    session->setWarningQueryId(session->getQueryId());
90
 
    session->warn_root.free_root(MYF(0));
91
 
    memset(session->warn_count, 0, sizeof(session->warn_count));
 
75
    thd->warn_id= thd->query_id;
 
76
    free_root(&thd->warn_root,MYF(0));
 
77
    memset(thd->warn_count, 0, sizeof(thd->warn_count));
92
78
    if (force)
93
 
      session->total_warn_count= 0;
94
 
    session->warn_list.empty();
95
 
    session->row_count= 1; // by default point to row 1
 
79
      thd->total_warn_count= 0;
 
80
    thd->warn_list.empty();
 
81
    thd->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
105
91
    push_warning()
106
 
    session                     Thread handle
 
92
    thd                 Thread handle
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
 
                          uint32_t code, const char *msg)
 
101
DRIZZLE_ERROR *push_warning(THD *thd, DRIZZLE_ERROR::enum_warning_level level, 
 
102
                          uint code, const char *msg)
117
103
{
118
104
  DRIZZLE_ERROR *err= 0;
119
105
 
120
106
  if (level == DRIZZLE_ERROR::WARN_LEVEL_NOTE &&
121
 
      !(session->options & OPTION_SQL_NOTES))
 
107
      !(thd->options & OPTION_SQL_NOTES))
122
108
    return(0);
123
109
 
124
 
  if (session->getQueryId() != session->getWarningQueryId())
125
 
    drizzle_reset_errors(session, 0);
126
 
  session->got_warning= 1;
 
110
  if (thd->query_id != thd->warn_id)
 
111
    drizzle_reset_errors(thd, 0);
 
112
  thd->got_warning= 1;
127
113
 
128
114
  /* Abort if we are using strict mode and we are not using IGNORE */
129
115
  if ((int) level >= (int) DRIZZLE_ERROR::WARN_LEVEL_WARN &&
130
 
      session->really_abort_on_warning())
 
116
      thd->really_abort_on_warning())
131
117
  {
132
118
    /* 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->setKilled(Session::KILL_BAD_DATA);
 
119
    bool no_warnings_for_error= thd->no_warnings_for_error;
 
120
 
 
121
    thd->no_warnings_for_error= 1;
 
122
 
 
123
    thd->killed= THD::KILL_BAD_DATA;
138
124
    my_message(code, msg, MYF(0));
139
125
 
140
 
    session->no_warnings_for_error= no_warnings_for_error;
 
126
    thd->no_warnings_for_error= no_warnings_for_error;
141
127
    /* Store error in error list (as my_message() didn't do it) */
142
128
    level= DRIZZLE_ERROR::WARN_LEVEL_ERROR;
143
129
  }
144
130
 
145
 
  if (session->handle_error(code, msg, level))
146
 
    return NULL;
 
131
  if (thd->handle_error(code, msg, level))
 
132
    return(NULL);
147
133
 
148
 
  if (session->warn_list.elements < session->variables.max_error_count)
 
134
  if (thd->warn_list.elements < thd->variables.max_error_count)
149
135
  {
150
136
    /* 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);
 
137
    if ((err= new (&thd->warn_root) DRIZZLE_ERROR(thd, code, level, msg)))
 
138
      thd->warn_list.push_back(err, &thd->warn_root);
153
139
  }
154
 
  session->warn_count[(uint32_t) level]++;
155
 
  session->total_warn_count++;
 
140
  thd->warn_count[(uint) level]++;
 
141
  thd->total_warn_count++;
156
142
  return(err);
157
143
}
158
144
 
161
147
 
162
148
  SYNOPSIS
163
149
    push_warning_printf()
164
 
    session                     Thread handle
 
150
    thd                 Thread handle
165
151
    level               Severity of warning (note, warning, error ...)
166
152
    code                Error number
167
153
    msg                 Clear error message
168
154
*/
169
155
 
170
 
void push_warning_printf(Session *session, DRIZZLE_ERROR::enum_warning_level level,
171
 
                         uint32_t code, const char *format, ...)
 
156
void push_warning_printf(THD *thd, DRIZZLE_ERROR::enum_warning_level level,
 
157
                         uint code, const char *format, ...)
172
158
{
173
159
  va_list args;
174
160
  char    warning[ERRMSGSIZE+20];
175
 
 
 
161
  
176
162
  va_start(args,format);
177
163
  vsnprintf(warning, sizeof(warning), format, args);
178
164
  va_end(args);
179
 
  push_warning(session, level, code, warning);
 
165
  push_warning(thd, level, code, warning);
180
166
  return;
181
167
}
182
168
 
186
172
 
187
173
  SYNOPSIS
188
174
    mysqld_show_warnings()
189
 
    session                     Thread handler
 
175
    thd                 Thread handler
190
176
    levels_to_show      Bitmap for which levels to show
191
177
 
192
178
  DESCRIPTION
205
191
  { C_STRING_WITH_LEN("?") }
206
192
};
207
193
 
208
 
bool mysqld_show_warnings(Session *session,
209
 
                          bitset<DRIZZLE_ERROR::NUM_ERRORS> &levels_to_show)
210
 
{
 
194
bool mysqld_show_warnings(THD *thd, uint32_t levels_to_show)
 
195
{  
211
196
  List<Item> field_list;
212
197
 
213
198
  field_list.push_back(new Item_empty_string("Level", 7));
214
199
  field_list.push_back(new Item_return_int("Code",4, DRIZZLE_TYPE_LONG));
215
200
  field_list.push_back(new Item_empty_string("Message",DRIZZLE_ERRMSG_SIZE));
216
201
 
217
 
  if (session->client->sendFields(&field_list))
218
 
    return true;
 
202
  if (thd->protocol->send_fields(&field_list,
 
203
                                 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
 
204
    return(true);
219
205
 
220
206
  DRIZZLE_ERROR *err;
221
 
  Select_Lex *sel= &session->lex->select_lex;
222
 
  Select_Lex_Unit *unit= &session->lex->unit;
 
207
  SELECT_LEX *sel= &thd->lex->select_lex;
 
208
  SELECT_LEX_UNIT *unit= &thd->lex->unit;
223
209
  ha_rows idx= 0;
 
210
  Protocol *protocol=thd->protocol;
224
211
 
225
212
  unit->set_limit(sel);
226
213
 
227
 
  List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
 
214
  List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
228
215
  while ((err= it++))
229
216
  {
230
217
    /* Skip levels that the user is not interested in */
231
 
    if (! levels_to_show.test(err->level))
 
218
    if (!(levels_to_show & ((ulong) 1 << err->level)))
232
219
      continue;
233
220
    if (++idx <= unit->offset_limit_cnt)
234
221
      continue;
235
222
    if (idx > unit->select_limit_cnt)
236
223
      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())
 
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())
242
230
      return(true);
243
231
  }
244
 
  session->my_eof();
 
232
  my_eof(thd);
245
233
  return(false);
246
234
}
247
 
 
248
 
} /* namespace drizzled */