26
26
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
27
27
/* Declared non-static only because of the embedded library. */
28
static void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err);
29
static void write_eof_packet(THD *thd, NET *net,
28
static void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err);
29
static void write_eof_packet(Session *session, NET *net,
30
30
uint32_t server_status, uint32_t total_warn_count);
32
32
bool Protocol::net_store_data(const unsigned char *from, size_t length)
115
115
critical that every error that can be intercepted is issued in one
116
116
place only, my_message_sql.
118
void net_send_error(THD *thd, uint32_t sql_errno, const char *err)
118
void net_send_error(Session *session, uint32_t sql_errno, const char *err)
120
120
assert(sql_errno);
121
121
assert(err && err[0]);
124
124
It's one case when we can push an error even though there
125
125
is an OK or EOF already.
127
thd->main_da.can_overwrite_status= true;
127
session->main_da.can_overwrite_status= true;
129
129
/* Abort multi-result sets */
130
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
132
net_send_error_packet(thd, sql_errno, err);
134
thd->main_da.can_overwrite_status= false;
130
session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
132
net_send_error_packet(session, sql_errno, err);
134
session->main_da.can_overwrite_status= false;
142
142
- 0 : Marker (1 byte)
143
143
- affected_rows : Stored in 1-9 bytes
144
144
- id : Stored in 1-9 bytes
145
- server_status : Copy of thd->server_status; Can be used by client
145
- server_status : Copy of session->server_status; Can be used by client
146
146
to check if we are inside an transaction.
147
147
New in 4.0 protocol
148
148
- warning_count : Stored in 2 bytes; New in 4.1 protocol
149
149
- message : Stored as packed length (1-9 bytes) + message.
150
150
Is not stored if no message.
152
@param thd Thread handler
152
@param session Thread handler
153
153
@param affected_rows Number of rows changed by statement
154
154
@param id Auto_increment id for first row (if used)
155
155
@param message Message to send to the client (Used by mysql_status)
159
net_send_ok(THD *thd,
159
net_send_ok(Session *session,
160
160
uint32_t server_status, uint32_t total_warn_count,
161
161
ha_rows affected_rows, uint64_t id, const char *message)
163
NET *net= &session->net;
164
164
unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
166
166
if (! net->vio) // hack for re-parsing queries
180
180
int2store(pos, tmp);
183
thd->main_da.can_overwrite_status= true;
183
session->main_da.can_overwrite_status= true;
185
185
if (message && message[0])
186
186
pos= net_store_data(pos, (unsigned char*) message, strlen(message));
187
187
my_net_write(net, buff, (size_t) (pos-buff));
190
thd->main_da.can_overwrite_status= false;
190
session->main_da.can_overwrite_status= false;
204
204
we don't want to report the warning count until all data is sent to the
207
@param thd Thread handler
207
@param session Thread handler
208
208
@param no_flush Set to 1 if there will be more data to the client,
209
209
like in send_fields().
213
net_send_eof(THD *thd, uint32_t server_status, uint32_t total_warn_count)
213
net_send_eof(Session *session, uint32_t server_status, uint32_t total_warn_count)
215
NET *net= &session->net;
216
216
/* Set to true if no active vio, to work well in case of --init-file */
217
217
if (net->vio != 0)
219
thd->main_da.can_overwrite_status= true;
220
write_eof_packet(thd, net, server_status, total_warn_count);
219
session->main_da.can_overwrite_status= true;
220
write_eof_packet(session, net, server_status, total_warn_count);
222
thd->main_da.can_overwrite_status= false;
222
session->main_da.can_overwrite_status= false;
229
229
write it to the network output buffer.
232
static void write_eof_packet(THD *thd, NET *net,
232
static void write_eof_packet(Session *session, NET *net,
233
233
uint32_t server_status,
234
234
uint32_t total_warn_count)
246
246
because if 'is_fatal_error' is set the server is not going to execute
247
247
other queries (see the if test in dispatch_command / COM_QUERY)
249
if (thd->is_fatal_error)
249
if (session->is_fatal_error)
250
250
server_status&= ~SERVER_MORE_RESULTS_EXISTS;
251
251
int2store(buff + 3, server_status);
252
252
my_net_write(net, buff, 5);
255
void net_send_error_packet(THD *thd, uint32_t sql_errno, const char *err)
255
void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err)
257
NET *net= &session->net;
260
260
buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
309
309
Send the status of the current statement execution over network.
311
@param thd in fact, carries two parameters, NET for the transport and
311
@param session in fact, carries two parameters, NET for the transport and
312
312
Diagnostics_area as the source of status information.
314
314
In MySQL, there are two types of SQL statements: those that return
355
355
Diagnostics_area::is_sent is set for debugging purposes only.
358
void net_end_statement(THD *thd)
358
void net_end_statement(Session *session)
360
assert(! thd->main_da.is_sent);
360
assert(! session->main_da.is_sent);
362
362
/* Can not be true, but do not take chances in production. */
363
if (thd->main_da.is_sent)
363
if (session->main_da.is_sent)
366
switch (thd->main_da.status()) {
366
switch (session->main_da.status()) {
367
367
case Diagnostics_area::DA_ERROR:
368
368
/* The query failed, send error to log and abort bootstrap. */
370
thd->main_da.sql_errno(),
371
thd->main_da.message());
369
net_send_error(session,
370
session->main_da.sql_errno(),
371
session->main_da.message());
373
373
case Diagnostics_area::DA_EOF:
375
thd->main_da.server_status(),
376
thd->main_da.total_warn_count());
374
net_send_eof(session,
375
session->main_da.server_status(),
376
session->main_da.total_warn_count());
378
378
case Diagnostics_area::DA_OK:
380
thd->main_da.server_status(),
381
thd->main_da.total_warn_count(),
382
thd->main_da.affected_rows(),
383
thd->main_da.last_insert_id(),
384
thd->main_da.message());
380
session->main_da.server_status(),
381
session->main_da.total_warn_count(),
382
session->main_da.affected_rows(),
383
session->main_da.last_insert_id(),
384
session->main_da.message());
386
386
case Diagnostics_area::DA_DISABLED:
388
388
case Diagnostics_area::DA_EMPTY:
391
net_send_ok(thd, thd->server_status, thd->total_warn_count,
391
net_send_ok(session, session->server_status, session->total_warn_count,
395
thd->main_da.is_sent= true;
395
session->main_da.is_sent= true;
433
433
Default Protocol functions
434
434
*****************************************************************************/
436
void Protocol::init(THD *thd_arg)
436
void Protocol::init(Session *session_arg)
439
packet= &thd->packet;
440
convert= &thd->convert_buffer;
439
packet= &session->packet;
440
convert= &session->convert_buffer;
449
void Protocol::end_partial_result_set(THD *thd)
449
void Protocol::end_partial_result_set(Session *session)
451
net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
451
net_send_eof(session, session->server_status, 0 /* no warnings, we're inside SP */);
455
455
bool Protocol::flush()
457
return net_flush(&thd->net);
457
return net_flush(&session->net);
483
483
unsigned char buff[80];
484
484
String tmp((char*) buff,sizeof(buff),&my_charset_bin);
485
Protocol_text prot(thd);
485
Protocol_text prot(session);
486
486
String *local_packet= prot.storage_packet();
487
const CHARSET_INFO * const thd_charset= thd->variables.character_set_results;
487
const CHARSET_INFO * const session_charset= session->variables.character_set_results;
489
489
if (flags & SEND_NUM_ROWS)
490
490
{ // Packet with number of elements
491
491
unsigned char *pos= net_store_length(buff, list->elements);
492
(void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
492
(void) my_net_write(&session->net, buff, (size_t) (pos-buff));
495
495
while ((item=it++))
502
502
prot.prepare_for_resend();
505
if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
505
if (prot.store(STRING_WITH_LEN("def"), cs, session_charset) ||
506
506
prot.store(field.db_name, (uint) strlen(field.db_name),
507
cs, session_charset) ||
508
508
prot.store(field.table_name, (uint) strlen(field.table_name),
509
cs, session_charset) ||
510
510
prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
511
cs, session_charset) ||
512
512
prot.store(field.col_name, (uint) strlen(field.col_name),
513
cs, session_charset) ||
514
514
prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
515
cs, session_charset) ||
516
516
local_packet->realloc(local_packet->length()+12))
519
519
/* Store fixed length fields */
520
520
pos= (char*) local_packet->ptr()+local_packet->length();
521
521
*pos++= 12; // Length of packed fields
522
if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
522
if (item->collation.collation == &my_charset_bin || session_charset == NULL)
524
524
/* No conversion */
525
525
int2store(pos, field.charsetnr);
530
530
/* With conversion */
531
531
uint32_t max_char_len;
532
int2store(pos, thd_charset->number);
532
int2store(pos, session_charset->number);
534
534
For TEXT/BLOB columns, field_length describes the maximum data
535
535
length in bytes. There is no limit to the number of characters
541
541
of characters here is limited by the column definition.
543
543
max_char_len= field.length / item->collation.collation->mbmaxlen;
544
int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
544
int4store(pos+2, max_char_len * session_charset->mbmaxlen);
546
546
pos[6]= field.type;
547
547
int2store(pos+7,field.flags);
560
560
if (flags & SEND_EOF)
563
Mark the end of meta-data result set, and store thd->server_status,
563
Mark the end of meta-data result set, and store session->server_status,
564
564
to show that there is no cursor.
565
565
Send no warning information, as it will be sent at statement end.
567
write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
567
write_eof_packet(session, &session->net, session->server_status, session->total_warn_count);
569
569
return(prepare_for_send(list));
683
683
bool Protocol_text::store(const char *from, size_t length,
684
684
const CHARSET_INFO * const fromcs)
686
const CHARSET_INFO * const tocs= this->thd->variables.character_set_results;
686
const CHARSET_INFO * const tocs= this->session->variables.character_set_results;
687
687
return store_string_aux(from, length, fromcs, tocs);
736
736
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
738
buffer->set_real((double) from, decimals, thd->charset());
738
buffer->set_real((double) from, decimals, session->charset());
739
739
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
743
743
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
745
buffer->set_real(from, decimals, thd->charset());
745
buffer->set_real(from, decimals, session->charset());
746
746
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());