~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 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
  @file
18
19
  Low level functions for storing data to be send to the MySQL client.
20
  The actual communction is handled by the net_xxx functions in net_serv.cc
21
*/
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
22
#include <drizzled/server_includes.h>
549 by Monty Taylor
Took gettext.h out of header files.
23
#include <drizzled/error.h>
468 by Monty Taylor
Repaced sql_state stuff with template function and c++ algorithm.
24
#include <drizzled/sql_state.h>
542 by Monty Taylor
Cleaned up the last commit.
25
#include <libdrizzle/pack.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.
26
#include <drizzled/protocol.h>
27
#include <drizzled/session.h>
1 by brian
clean slate
28
29
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
30
/* Declared non-static only because of the embedded library. */
520.1.22 by Brian Aker
Second pass of thd cleanup
31
static void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err);
32
static void write_eof_packet(Session *session, NET *net,
482 by Brian Aker
Remove uint.
33
                             uint32_t server_status, uint32_t total_warn_count);
1 by brian
clean slate
34
481 by Brian Aker
Remove all of uchar.
35
bool Protocol::net_store_data(const unsigned char *from, size_t length)
1 by brian
clean slate
36
{
628 by Brian Aker
Collection of dead code removal
37
  size_t packet_length= packet->length();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
38
  /*
1 by brian
clean slate
39
     The +9 comes from that strings of length longer than 16M require
40
     9 bytes to be stored (see net_store_length).
41
  */
42
  if (packet_length+9+length > packet->alloced_length() &&
43
      packet->realloc(packet_length+9+length))
44
    return 1;
481 by Brian Aker
Remove all of uchar.
45
  unsigned char *to= net_store_length((unsigned char*) packet->ptr()+packet_length, length);
1 by brian
clean slate
46
  memcpy(to,from,length);
628 by Brian Aker
Collection of dead code removal
47
  packet->length((size_t) (to+length-(unsigned char*) packet->ptr()));
1 by brian
clean slate
48
  return 0;
49
}
50
51
52
53
54
/*
55
  net_store_data() - extended version with character set conversion.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
56
1 by brian
clean slate
57
  It is optimized for short strings whose length after
58
  conversion is garanteed to be less than 251, which accupies
59
  exactly one byte to store length. It allows not to use
60
  the "convert" member as a temporary buffer, conversion
61
  is done directly to the "packet" member.
62
  The limit 251 is good enough to optimize send_fields()
63
  because column, table, database names fit into this limit.
64
*/
65
481 by Brian Aker
Remove all of uchar.
66
bool Protocol::net_store_data(const unsigned char *from, size_t length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
67
                              const CHARSET_INFO * const from_cs,
68
							  const CHARSET_INFO * const to_cs)
1 by brian
clean slate
69
{
482 by Brian Aker
Remove uint.
70
  uint32_t dummy_errors;
1 by brian
clean slate
71
  /* Calculate maxumum possible result length */
482 by Brian Aker
Remove uint.
72
  uint32_t conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
1 by brian
clean slate
73
  if (conv_length > 250)
74
  {
75
    /*
76
      For strings with conv_length greater than 250 bytes
77
      we don't know how many bytes we will need to store length: one or two,
78
      because we don't know result length until conversion is done.
79
      For example, when converting from utf8 (mbmaxlen=3) to latin1,
80
      conv_length=300 means that the result length can vary between 100 to 300.
81
      length=100 needs one byte, length=300 needs to bytes.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
82
1 by brian
clean slate
83
      Thus conversion directly to "packet" is not worthy.
84
      Let's use "convert" as a temporary buffer.
85
    */
86
    return (convert->copy((const char*) from, length, from_cs,
87
                          to_cs, &dummy_errors) ||
481 by Brian Aker
Remove all of uchar.
88
            net_store_data((const unsigned char*) convert->ptr(), convert->length()));
1 by brian
clean slate
89
  }
90
628 by Brian Aker
Collection of dead code removal
91
  size_t packet_length= packet->length();
92
  size_t new_length= packet_length + conv_length + 1;
1 by brian
clean slate
93
94
  if (new_length > packet->alloced_length() && packet->realloc(new_length))
95
    return 1;
96
97
  char *length_pos= (char*) packet->ptr() + packet_length;
98
  char *to= length_pos + 1;
99
100
  to+= copy_and_convert(to, conv_length, to_cs,
101
                        (const char*) from, length, from_cs, &dummy_errors);
102
481 by Brian Aker
Remove all of uchar.
103
  net_store_length((unsigned char*) length_pos, to - length_pos - 1);
1 by brian
clean slate
104
  packet->length((uint) (to - packet->ptr()));
105
  return 0;
106
}
107
108
109
/**
110
  Send a error string to client.
111
112
  Design note:
113
  net_printf_error and net_send_error are low-level functions
114
  that shall be used only when a new connection is being
115
  established or at server startup.
116
117
  For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
118
  critical that every error that can be intercepted is issued in one
119
  place only, my_message_sql.
120
*/
520.1.22 by Brian Aker
Second pass of thd cleanup
121
void net_send_error(Session *session, uint32_t sql_errno, const char *err)
1 by brian
clean slate
122
{
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
123
  assert(sql_errno);
124
  assert(err && err[0]);
1 by brian
clean slate
125
126
  /*
127
    It's one case when we can push an error even though there
128
    is an OK or EOF already.
129
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
130
  session->main_da.can_overwrite_status= true;
1 by brian
clean slate
131
132
  /* Abort multi-result sets */
520.1.22 by Brian Aker
Second pass of thd cleanup
133
  session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
134
135
  net_send_error_packet(session, sql_errno, err);
136
137
  session->main_da.can_overwrite_status= false;
1 by brian
clean slate
138
}
139
140
/**
141
  Return ok to the client.
142
143
  The ok packet has the following structure:
144
145
  - 0               : Marker (1 byte)
146
  - affected_rows	: Stored in 1-9 bytes
147
  - id		: Stored in 1-9 bytes
520.1.22 by Brian Aker
Second pass of thd cleanup
148
  - server_status	: Copy of session->server_status;  Can be used by client
1 by brian
clean slate
149
  to check if we are inside an transaction.
150
  New in 4.0 protocol
151
  - warning_count	: Stored in 2 bytes; New in 4.1 protocol
152
  - message		: Stored as packed length (1-9 bytes) + message.
153
  Is not stored if no message.
154
520.1.22 by Brian Aker
Second pass of thd cleanup
155
  @param session		   Thread handler
1 by brian
clean slate
156
  @param affected_rows	   Number of rows changed by statement
157
  @param id		   Auto_increment id for first row (if used)
158
  @param message	   Message to send to the client (Used by mysql_status)
159
*/
160
202.1.17 by Monty Taylor
Patch from andrey - made some functions static as they are not used outside of protocol.cc.
161
static void
520.1.22 by Brian Aker
Second pass of thd cleanup
162
net_send_ok(Session *session,
482 by Brian Aker
Remove uint.
163
            uint32_t server_status, uint32_t total_warn_count,
151 by Brian Aker
Ulonglong to uint64_t
164
            ha_rows affected_rows, uint64_t id, const char *message)
1 by brian
clean slate
165
{
520.1.22 by Brian Aker
Second pass of thd cleanup
166
  NET *net= &session->net;
481 by Brian Aker
Remove all of uchar.
167
  unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
1 by brian
clean slate
168
169
  if (! net->vio)	// hack for re-parsing queries
170
  {
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
171
    return;
1 by brian
clean slate
172
  }
173
174
  buff[0]=0;					// No fields
175
  pos=net_store_length(buff+1,affected_rows);
176
  pos=net_store_length(pos, id);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
177
178
  int2store(pos, server_status);
179
  pos+=2;
180
181
  /* We can only return up to 65535 warnings in two bytes */
482 by Brian Aker
Remove uint.
182
  uint32_t tmp= cmin(total_warn_count, (uint)65535);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
183
  int2store(pos, tmp);
184
  pos+= 2;
185
520.1.22 by Brian Aker
Second pass of thd cleanup
186
  session->main_da.can_overwrite_status= true;
1 by brian
clean slate
187
188
  if (message && message[0])
481 by Brian Aker
Remove all of uchar.
189
    pos= net_store_data(pos, (unsigned char*) message, strlen(message));
398.1.10 by Monty Taylor
Actually removed VOID() this time.
190
  my_net_write(net, buff, (size_t) (pos-buff));
191
  net_flush(net);
1 by brian
clean slate
192
520.1.22 by Brian Aker
Second pass of thd cleanup
193
  session->main_da.can_overwrite_status= false;
1 by brian
clean slate
194
}
195
196
/**
197
  Send eof (= end of result set) to the client.
198
199
  The eof packet has the following structure:
200
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
201
  - 254	(DRIZZLE_PROTOCOL_NO_MORE_DATA)	: Marker (1 byte)
1 by brian
clean slate
202
  - warning_count	: Stored in 2 bytes; New in 4.1 protocol
203
  - status_flag	: Stored in 2 bytes;
204
  For flags like SERVER_MORE_RESULTS_EXISTS.
205
206
  Note that the warning count will not be sent if 'no_flush' is set as
207
  we don't want to report the warning count until all data is sent to the
208
  client.
209
520.1.22 by Brian Aker
Second pass of thd cleanup
210
  @param session		Thread handler
1 by brian
clean slate
211
  @param no_flush	Set to 1 if there will be more data to the client,
212
                    like in send_fields().
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
213
*/
1 by brian
clean slate
214
202.1.17 by Monty Taylor
Patch from andrey - made some functions static as they are not used outside of protocol.cc.
215
static void
520.1.22 by Brian Aker
Second pass of thd cleanup
216
net_send_eof(Session *session, uint32_t server_status, uint32_t total_warn_count)
1 by brian
clean slate
217
{
520.1.22 by Brian Aker
Second pass of thd cleanup
218
  NET *net= &session->net;
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
219
  /* Set to true if no active vio, to work well in case of --init-file */
1 by brian
clean slate
220
  if (net->vio != 0)
221
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
222
    session->main_da.can_overwrite_status= true;
223
    write_eof_packet(session, net, server_status, total_warn_count);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
224
    net_flush(net);
520.1.22 by Brian Aker
Second pass of thd cleanup
225
    session->main_da.can_overwrite_status= false;
1 by brian
clean slate
226
  }
227
}
228
229
230
/**
231
  Format EOF packet according to the current protocol and
232
  write it to the network output buffer.
233
*/
234
520.1.22 by Brian Aker
Second pass of thd cleanup
235
static void write_eof_packet(Session *session, NET *net,
482 by Brian Aker
Remove uint.
236
                             uint32_t server_status,
237
                             uint32_t total_warn_count)
1 by brian
clean slate
238
{
481 by Brian Aker
Remove all of uchar.
239
  unsigned char buff[5];
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
240
  /*
241
    Don't send warn count during SP execution, as the warn_list
242
    is cleared between substatements, and mysqltest gets confused
243
  */
482 by Brian Aker
Remove uint.
244
  uint32_t tmp= cmin(total_warn_count, (uint)65535);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
245
  buff[0]= DRIZZLE_PROTOCOL_NO_MORE_DATA;
246
  int2store(buff+1, tmp);
247
  /*
248
    The following test should never be true, but it's better to do it
249
    because if 'is_fatal_error' is set the server is not going to execute
250
    other queries (see the if test in dispatch_command / COM_QUERY)
251
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
252
  if (session->is_fatal_error)
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
253
    server_status&= ~SERVER_MORE_RESULTS_EXISTS;
254
  int2store(buff + 3, server_status);
398.1.10 by Monty Taylor
Actually removed VOID() this time.
255
  my_net_write(net, buff, 5);
1 by brian
clean slate
256
}
257
520.1.22 by Brian Aker
Second pass of thd cleanup
258
void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err)
1 by brian
clean slate
259
{
520.1.22 by Brian Aker
Second pass of thd cleanup
260
  NET *net= &session->net;
482 by Brian Aker
Remove uint.
261
  uint32_t length;
1 by brian
clean slate
262
  /*
261.4.1 by Felipe
- Renamed MYSQL_ERROR to DRIZZLE_ERROR.
263
    buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + DRIZZLE_ERRMSG_SIZE:512
1 by brian
clean slate
264
  */
481 by Brian Aker
Remove all of uchar.
265
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
1 by brian
clean slate
266
267
  if (net->vio == 0)
268
  {
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
269
    return;
1 by brian
clean slate
270
  }
271
272
  int2store(buff,sql_errno);
273
  pos= buff+2;
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
274
275
  /* The first # is to make the protocol backward compatible */
276
  buff[2]= '#';
641.4.3 by Toru Maesaka
Final pass of replacing MySQL's my_stpcpy() with appropriate libc calls
277
  pos= (unsigned char*) strcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
278
  pos+= strlen(drizzle_errno_to_sqlstate(sql_errno));
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
279
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
280
  char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1);
281
  tmp+= strlen((char*)pos);
282
  tmp[0]= '\0';
283
  length= (uint32_t)(tmp-(char*)buff);
1 by brian
clean slate
284
  err= (char*) buff;
285
481 by Brian Aker
Remove all of uchar.
286
  net_write_command(net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
287
  return;
1 by brian
clean slate
288
}
289
290
291
/**
292
  Faster net_store_length when we know that length is less than 65536.
293
  We keep a separate version for that range because it's widely used in
294
  libmysql.
295
482 by Brian Aker
Remove uint.
296
  uint32_t is used as agrument type because of MySQL type conventions:
297
  - uint32_t for 0..65536
1 by brian
clean slate
298
  - ulong for 0..4294967296
151 by Brian Aker
Ulonglong to uint64_t
299
  - uint64_t for bigger numbers.
1 by brian
clean slate
300
*/
301
482 by Brian Aker
Remove uint.
302
static unsigned char *net_store_length_fast(unsigned char *packet, uint32_t length)
1 by brian
clean slate
303
{
304
  if (length < 251)
305
  {
481 by Brian Aker
Remove all of uchar.
306
    *packet=(unsigned char) length;
1 by brian
clean slate
307
    return packet+1;
308
  }
309
  *packet++=252;
628 by Brian Aker
Collection of dead code removal
310
  int2store(packet,(uint32_t) length);
311
1 by brian
clean slate
312
  return packet+2;
313
}
314
315
/**
316
  Send the status of the current statement execution over network.
317
520.1.22 by Brian Aker
Second pass of thd cleanup
318
  @param  session   in fact, carries two parameters, NET for the transport and
1 by brian
clean slate
319
                Diagnostics_area as the source of status information.
320
321
  In MySQL, there are two types of SQL statements: those that return
322
  a result set and those that return status information only.
323
324
  If a statement returns a result set, it consists of 3 parts:
325
  - result set meta-data
326
  - variable number of result set rows (can be 0)
327
  - followed and terminated by EOF or ERROR packet
328
329
  Once the  client has seen the meta-data information, it always
330
  expects an EOF or ERROR to terminate the result set. If ERROR is
331
  received, the result set rows are normally discarded (this is up
332
  to the client implementation, libmysql at least does discard them).
333
  EOF, on the contrary, means "successfully evaluated the entire
334
  result set". Since we don't know how many rows belong to a result
335
  set until it's evaluated, EOF/ERROR is the indicator of the end
336
  of the row stream. Note, that we can not buffer result set rows
337
  on the server -- there may be an arbitrary number of rows. But
338
  we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
339
  delay sending it till the very end of execution (here), to be able to
340
  change EOF to an ERROR if commit failed or some other error occurred
341
  during the last cleanup steps taken after execution.
342
343
  A statement that does not return a result set doesn't send result
344
  set meta-data either. Instead it returns one of:
345
  - OK packet
346
  - ERROR packet.
347
  Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
348
  packet is "buffered" in the diagnostics area and sent to the client
349
  in the end of statement.
350
351
  @pre  The diagnostics area is assigned or disabled. It can not be empty
352
        -- we assume that every SQL statement or COM_* command
353
        generates OK, ERROR, or EOF status.
354
355
  @post The status information is encoded to protocol format and sent to the
356
        client.
357
358
  @return We conventionally return void, since the only type of error
359
          that can happen here is a NET (transport) error, and that one
360
          will become visible when we attempt to read from the NET the
361
          next command.
362
          Diagnostics_area::is_sent is set for debugging purposes only.
363
*/
364
520.1.22 by Brian Aker
Second pass of thd cleanup
365
void net_end_statement(Session *session)
1 by brian
clean slate
366
{
520.1.22 by Brian Aker
Second pass of thd cleanup
367
  assert(! session->main_da.is_sent);
1 by brian
clean slate
368
369
  /* Can not be true, but do not take chances in production. */
520.1.22 by Brian Aker
Second pass of thd cleanup
370
  if (session->main_da.is_sent)
1 by brian
clean slate
371
    return;
372
520.1.22 by Brian Aker
Second pass of thd cleanup
373
  switch (session->main_da.status()) {
1 by brian
clean slate
374
  case Diagnostics_area::DA_ERROR:
375
    /* The query failed, send error to log and abort bootstrap. */
520.1.22 by Brian Aker
Second pass of thd cleanup
376
    net_send_error(session,
377
                   session->main_da.sql_errno(),
378
                   session->main_da.message());
1 by brian
clean slate
379
    break;
380
  case Diagnostics_area::DA_EOF:
520.1.22 by Brian Aker
Second pass of thd cleanup
381
    net_send_eof(session,
382
                 session->main_da.server_status(),
383
                 session->main_da.total_warn_count());
1 by brian
clean slate
384
    break;
385
  case Diagnostics_area::DA_OK:
520.1.22 by Brian Aker
Second pass of thd cleanup
386
    net_send_ok(session,
387
                session->main_da.server_status(),
388
                session->main_da.total_warn_count(),
389
                session->main_da.affected_rows(),
390
                session->main_da.last_insert_id(),
391
                session->main_da.message());
1 by brian
clean slate
392
    break;
393
  case Diagnostics_area::DA_DISABLED:
394
    break;
395
  case Diagnostics_area::DA_EMPTY:
396
  default:
722.2.12 by Monty Taylor
Removed assert(0); Added function ptr in libdrizzle.
397
    //TODO: Something is being masked here by commenting this out
398
    //  assert(0);
520.1.22 by Brian Aker
Second pass of thd cleanup
399
    net_send_ok(session, session->server_status, session->total_warn_count,
1 by brian
clean slate
400
                0, 0, NULL);
401
    break;
402
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
403
  session->main_da.is_sent= true;
1 by brian
clean slate
404
}
405
406
407
/****************************************************************************
408
  Functions used by the protocol functions (like net_send_ok) to store
409
  strings and numbers in the header result packet.
410
****************************************************************************/
411
412
/* The following will only be used for short strings < 65K */
413
481 by Brian Aker
Remove all of uchar.
414
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
1 by brian
clean slate
415
{
416
  to=net_store_length_fast(to,length);
417
  memcpy(to,from,length);
418
  return to+length;
419
}
420
481 by Brian Aker
Remove all of uchar.
421
unsigned char *net_store_data(unsigned char *to,int32_t from)
1 by brian
clean slate
422
{
423
  char buff[20];
482 by Brian Aker
Remove uint.
424
  uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
1 by brian
clean slate
425
  to=net_store_length_fast(to,length);
426
  memcpy(to,buff,length);
427
  return to+length;
428
}
429
481 by Brian Aker
Remove all of uchar.
430
unsigned char *net_store_data(unsigned char *to,int64_t from)
1 by brian
clean slate
431
{
432
  char buff[22];
482 by Brian Aker
Remove uint.
433
  uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
1 by brian
clean slate
434
  to=net_store_length_fast(to,length);
435
  memcpy(to,buff,length);
436
  return to+length;
437
}
438
439
440
/*****************************************************************************
441
  Default Protocol functions
442
*****************************************************************************/
443
520.1.22 by Brian Aker
Second pass of thd cleanup
444
void Protocol::init(Session *session_arg)
1 by brian
clean slate
445
{
520.1.22 by Brian Aker
Second pass of thd cleanup
446
  session=session_arg;
447
  packet= &session->packet;
448
  convert= &session->convert_buffer;
1 by brian
clean slate
449
}
450
451
/**
452
  Finish the result set with EOF packet, as is expected by the client,
453
  if there is an error evaluating the next row and a continue handler
454
  for the error.
455
*/
456
520.1.22 by Brian Aker
Second pass of thd cleanup
457
void Protocol::end_partial_result_set(Session *session)
1 by brian
clean slate
458
{
520.1.22 by Brian Aker
Second pass of thd cleanup
459
  net_send_eof(session, session->server_status, 0 /* no warnings, we're inside SP */);
1 by brian
clean slate
460
}
461
462
463
bool Protocol::flush()
464
{
520.1.22 by Brian Aker
Second pass of thd cleanup
465
  return net_flush(&session->net);
1 by brian
clean slate
466
}
467
468
469
/**
470
  Send name and type of result to client.
471
472
  Sum fields has table name empty and field_name.
473
520.1.21 by Brian Aker
THD -> Session rename
474
  @param Session		Thread data object
1 by brian
clean slate
475
  @param list	        List of items to send to client
476
  @param flag	        Bit mask with the following functions:
477
                        - 1 send number of rows
478
                        - 2 send default values
479
                        - 4 don't write eof packet
480
481
  @retval
482
    0	ok
483
  @retval
484
    1	Error  (Note that in this case the error is not sent to the
485
    client)
486
*/
482 by Brian Aker
Remove uint.
487
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
1 by brian
clean slate
488
{
489
  List_iterator_fast<Item> it(*list);
490
  Item *item;
481 by Brian Aker
Remove all of uchar.
491
  unsigned char buff[80];
1 by brian
clean slate
492
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
520.1.22 by Brian Aker
Second pass of thd cleanup
493
  Protocol_text prot(session);
1 by brian
clean slate
494
  String *local_packet= prot.storage_packet();
748 by Brian Aker
Removal of client side collation.
495
  const CHARSET_INFO * const session_charset= default_charset_info;
1 by brian
clean slate
496
497
  if (flags & SEND_NUM_ROWS)
498
  {				// Packet with number of elements
481 by Brian Aker
Remove all of uchar.
499
    unsigned char *pos= net_store_length(buff, list->elements);
520.1.22 by Brian Aker
Second pass of thd cleanup
500
    (void) my_net_write(&session->net, buff, (size_t) (pos-buff));
1 by brian
clean slate
501
  }
502
503
  while ((item=it++))
504
  {
505
    char *pos;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
506
    const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
507
    Send_field field;
508
    item->make_field(&field);
509
510
    prot.prepare_for_resend();
511
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
512
520.1.22 by Brian Aker
Second pass of thd cleanup
513
    if (prot.store(STRING_WITH_LEN("def"), cs, session_charset) ||
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
514
        prot.store(field.db_name, (uint) strlen(field.db_name),
520.1.22 by Brian Aker
Second pass of thd cleanup
515
                   cs, session_charset) ||
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
516
        prot.store(field.table_name, (uint) strlen(field.table_name),
520.1.22 by Brian Aker
Second pass of thd cleanup
517
                   cs, session_charset) ||
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
518
        prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
520.1.22 by Brian Aker
Second pass of thd cleanup
519
                   cs, session_charset) ||
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
520
        prot.store(field.col_name, (uint) strlen(field.col_name),
520.1.22 by Brian Aker
Second pass of thd cleanup
521
                   cs, session_charset) ||
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
522
        prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
520.1.22 by Brian Aker
Second pass of thd cleanup
523
                   cs, session_charset) ||
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
524
        local_packet->realloc(local_packet->length()+12))
525
      goto err;
526
527
    /* Store fixed length fields */
528
    pos= (char*) local_packet->ptr()+local_packet->length();
529
    *pos++= 12;				// Length of packed fields
520.1.22 by Brian Aker
Second pass of thd cleanup
530
    if (item->collation.collation == &my_charset_bin || session_charset == NULL)
1 by brian
clean slate
531
    {
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
532
      /* No conversion */
533
      int2store(pos, field.charsetnr);
534
      int4store(pos+2, field.length);
1 by brian
clean slate
535
    }
536
    else
537
    {
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
538
      /* With conversion */
482 by Brian Aker
Remove uint.
539
      uint32_t max_char_len;
520.1.22 by Brian Aker
Second pass of thd cleanup
540
      int2store(pos, session_charset->number);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
541
      /*
542
        For TEXT/BLOB columns, field_length describes the maximum data
543
        length in bytes. There is no limit to the number of characters
544
        that a TEXT column can store, as long as the data fits into
545
        the designated space.
546
        For the rest of textual columns, field_length is evaluated as
547
        char_count * mbmaxlen, where character count is taken from the
548
        definition of the column. In other words, the maximum number
549
        of characters here is limited by the column definition.
550
      */
551
      max_char_len= field.length / item->collation.collation->mbmaxlen;
520.1.22 by Brian Aker
Second pass of thd cleanup
552
      int4store(pos+2, max_char_len * session_charset->mbmaxlen);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
553
    }
554
    pos[6]= field.type;
555
    int2store(pos+7,field.flags);
556
    pos[9]= (char) field.decimals;
557
    pos[10]= 0;				// For the future
558
    pos[11]= 0;				// For the future
559
    pos+= 12;
1 by brian
clean slate
560
561
    local_packet->length((uint) (pos - local_packet->ptr()));
562
    if (flags & SEND_DEFAULTS)
563
      item->send(&prot, &tmp);			// Send default value
564
    if (prot.write())
565
      break;					/* purecov: inspected */
566
  }
567
568
  if (flags & SEND_EOF)
569
  {
570
    /*
520.1.22 by Brian Aker
Second pass of thd cleanup
571
      Mark the end of meta-data result set, and store session->server_status,
1 by brian
clean slate
572
      to show that there is no cursor.
573
      Send no warning information, as it will be sent at statement end.
574
    */
520.1.22 by Brian Aker
Second pass of thd cleanup
575
    write_eof_packet(session, &session->net, session->server_status, session->total_warn_count);
1 by brian
clean slate
576
  }
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
577
  return(prepare_for_send(list));
1 by brian
clean slate
578
579
err:
580
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
581
             MYF(0));	/* purecov: inspected */
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
582
  return(1);				/* purecov: inspected */
1 by brian
clean slate
583
}
584
585
586
bool Protocol::write()
587
{
520.1.22 by Brian Aker
Second pass of thd cleanup
588
  return(my_net_write(&session->net, (unsigned char*) packet->ptr(),
1 by brian
clean slate
589
                           packet->length()));
590
}
591
592
593
/**
594
  Send \\0 end terminated string.
595
461 by Monty Taylor
Removed NullS. bu-bye.
596
  @param from	NULL or \\0 terminated string
1 by brian
clean slate
597
598
  @note
599
    In most cases one should use store(from, length) instead of this function
600
601
  @retval
602
    0		ok
603
  @retval
604
    1		error
605
*/
606
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
607
bool Protocol::store(const char *from, const CHARSET_INFO * const cs)
1 by brian
clean slate
608
{
609
  if (!from)
610
    return store_null();
482 by Brian Aker
Remove uint.
611
  uint32_t length= strlen(from);
1 by brian
clean slate
612
  return store(from, length, cs);
613
}
614
615
616
/**
617
  Send a set of strings as one long string with ',' in between.
618
*/
619
620
bool Protocol::store(I_List<i_string>* str_list)
621
{
622
  char buf[256];
623
  String tmp(buf, sizeof(buf), &my_charset_bin);
205 by Brian Aker
uint32 -> uin32_t
624
  uint32_t len;
1 by brian
clean slate
625
  I_List_iterator<i_string> it(*str_list);
626
  i_string* s;
627
628
  tmp.length(0);
629
  while ((s=it++))
630
  {
631
    tmp.append(s->ptr);
632
    tmp.append(',');
633
  }
634
  if ((len= tmp.length()))
635
    len--;					// Remove last ','
636
  return store((char*) tmp.ptr(), len,  tmp.charset());
637
}
638
639
584.1.14 by Monty Taylor
Removed field.h from common_includes.
640
bool Protocol::store(String *str)
641
{
642
  return store((char*) str->ptr(), str->length(), str->charset());
643
}
644
645
void Protocol::free()
646
{
647
  packet->free();
648
}
649
650
1 by brian
clean slate
651
/****************************************************************************
652
  Functions to handle the simple (default) protocol where everything is
653
  This protocol is the one that is used by default between the MySQL server
654
  and client when you are not using prepared statements.
655
656
  All data are sent as 'packed-string-length' followed by 'string-data'
657
****************************************************************************/
658
659
void Protocol_text::prepare_for_resend()
660
{
661
  packet->length(0);
662
}
663
664
bool Protocol_text::store_null()
665
{
666
  char buff[1];
667
  buff[0]= (char)251;
668
  return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
669
}
670
671
672
/**
673
  Auxilary function to convert string to the given character set
674
  and store in network buffer.
675
*/
676
677
bool Protocol::store_string_aux(const char *from, size_t length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
678
                                const CHARSET_INFO * const fromcs,
679
								const CHARSET_INFO * const tocs)
1 by brian
clean slate
680
{
681
  /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
682
  if (tocs && !my_charset_same(fromcs, tocs) &&
683
      fromcs != &my_charset_bin &&
684
      tocs != &my_charset_bin)
685
  {
686
    /* Store with conversion */
481 by Brian Aker
Remove all of uchar.
687
    return net_store_data((unsigned char*) from, length, fromcs, tocs);
1 by brian
clean slate
688
  }
689
  /* Store without conversion */
481 by Brian Aker
Remove all of uchar.
690
  return net_store_data((unsigned char*) from, length);
1 by brian
clean slate
691
}
692
693
694
bool Protocol_text::store(const char *from, size_t length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
695
                          const CHARSET_INFO * const fromcs,
696
						  const CHARSET_INFO * const tocs)
1 by brian
clean slate
697
{
698
  return store_string_aux(from, length, fromcs, tocs);
699
}
700
701
702
bool Protocol_text::store(const char *from, size_t length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
703
                          const CHARSET_INFO * const fromcs)
1 by brian
clean slate
704
{
748 by Brian Aker
Removal of client side collation.
705
  const CHARSET_INFO * const tocs= default_charset_info;
1 by brian
clean slate
706
  return store_string_aux(from, length, fromcs, tocs);
707
}
708
709
152 by Brian Aker
longlong replacement
710
bool Protocol_text::store_tiny(int64_t from)
1 by brian
clean slate
711
{
712
  char buff[20];
481 by Brian Aker
Remove all of uchar.
713
  return net_store_data((unsigned char*) buff,
1 by brian
clean slate
714
			(size_t) (int10_to_str((int) from, buff, -10) - buff));
715
}
716
717
152 by Brian Aker
longlong replacement
718
bool Protocol_text::store_short(int64_t from)
1 by brian
clean slate
719
{
720
  char buff[20];
481 by Brian Aker
Remove all of uchar.
721
  return net_store_data((unsigned char*) buff,
1 by brian
clean slate
722
			(size_t) (int10_to_str((int) from, buff, -10) -
723
                                  buff));
724
}
725
726
152 by Brian Aker
longlong replacement
727
bool Protocol_text::store_long(int64_t from)
1 by brian
clean slate
728
{
729
  char buff[20];
481 by Brian Aker
Remove all of uchar.
730
  return net_store_data((unsigned char*) buff,
1 by brian
clean slate
731
			(size_t) (int10_to_str((long int)from, buff,
732
                                               (from <0)?-10:10)-buff));
733
}
734
735
152 by Brian Aker
longlong replacement
736
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
1 by brian
clean slate
737
{
738
  char buff[22];
481 by Brian Aker
Remove all of uchar.
739
  return net_store_data((unsigned char*) buff,
152 by Brian Aker
longlong replacement
740
			(size_t) (int64_t10_to_str(from,buff,
1 by brian
clean slate
741
                                                    unsigned_flag ? 10 : -10)-
742
                                  buff));
743
}
744
745
746
bool Protocol_text::store_decimal(const my_decimal *d)
747
{
748
  char buff[DECIMAL_MAX_STR_LENGTH];
749
  String str(buff, sizeof(buff), &my_charset_bin);
750
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
481 by Brian Aker
Remove all of uchar.
751
  return net_store_data((unsigned char*) str.ptr(), str.length());
1 by brian
clean slate
752
}
753
754
205 by Brian Aker
uint32 -> uin32_t
755
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
1 by brian
clean slate
756
{
520.1.22 by Brian Aker
Second pass of thd cleanup
757
  buffer->set_real((double) from, decimals, session->charset());
481 by Brian Aker
Remove all of uchar.
758
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
1 by brian
clean slate
759
}
760
761
205 by Brian Aker
uint32 -> uin32_t
762
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
1 by brian
clean slate
763
{
520.1.22 by Brian Aker
Second pass of thd cleanup
764
  buffer->set_real(from, decimals, session->charset());
481 by Brian Aker
Remove all of uchar.
765
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
1 by brian
clean slate
766
}
767
768
769
bool Protocol_text::store(Field *field)
770
{
771
  if (field->is_null())
772
    return store_null();
773
  char buff[MAX_FIELD_WIDTH];
774
  String str(buff,sizeof(buff), &my_charset_bin);
748 by Brian Aker
Removal of client side collation.
775
  const CHARSET_INFO * const tocs= default_charset_info;
1 by brian
clean slate
776
777
  field->val_str(&str);
778
779
  return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
780
}
781
782
783
/**
784
  @todo
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
785
    Second_part format ("%06") needs to change when
1 by brian
clean slate
786
    we support 0-6 decimals for time.
787
*/
788
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
789
bool Protocol_text::store(DRIZZLE_TIME *tm)
1 by brian
clean slate
790
{
791
  char buff[40];
482 by Brian Aker
Remove uint.
792
  uint32_t length;
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
793
  length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
1 by brian
clean slate
794
			   (int) tm->year,
795
			   (int) tm->month,
796
			   (int) tm->day,
797
			   (int) tm->hour,
798
			   (int) tm->minute,
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
799
			   (int) tm->second);
1 by brian
clean slate
800
  if (tm->second_part)
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
801
    length+= sprintf(buff+length, ".%06d",
802
                                     (int)tm->second_part);
481 by Brian Aker
Remove all of uchar.
803
  return net_store_data((unsigned char*) buff, length);
1 by brian
clean slate
804
}
805
806
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
807
bool Protocol_text::store_date(DRIZZLE_TIME *tm)
1 by brian
clean slate
808
{
809
  char buff[MAX_DATE_STRING_REP_LENGTH];
810
  size_t length= my_date_to_str(tm, buff);
481 by Brian Aker
Remove all of uchar.
811
  return net_store_data((unsigned char*) buff, length);
1 by brian
clean slate
812
}
813
814
815
/**
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
816
  @todo
817
    Second_part format ("%06") needs to change when
1 by brian
clean slate
818
    we support 0-6 decimals for time.
819
*/
820
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
821
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
1 by brian
clean slate
822
{
823
  char buff[40];
482 by Brian Aker
Remove uint.
824
  uint32_t length;
825
  uint32_t day= (tm->year || tm->month) ? 0 : tm->day;
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
826
  length= sprintf(buff, "%s%02ld:%02d:%02d",
1 by brian
clean slate
827
			   tm->neg ? "-" : "",
828
			   (long) day*24L+(long) tm->hour,
829
			   (int) tm->minute,
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
830
			   (int) tm->second);
1 by brian
clean slate
831
  if (tm->second_part)
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
832
    length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
481 by Brian Aker
Remove all of uchar.
833
  return net_store_data((unsigned char*) buff, length);
1 by brian
clean slate
834
}
835