~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();
1 by brian
clean slate
38
  /* 
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.
56
  
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.
82
      
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().
213
*/    
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]= '#';
481 by Brian Aker
Remove all of uchar.
277
  pos= (unsigned char*) my_stpcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
278
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
279
  char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1);
280
  tmp+= strlen((char*)pos);
281
  tmp[0]= '\0';
282
  length= (uint32_t)(tmp-(char*)buff);
1 by brian
clean slate
283
  err= (char*) buff;
284
481 by Brian Aker
Remove all of uchar.
285
  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
286
  return;
1 by brian
clean slate
287
}
288
289
290
/**
291
  Faster net_store_length when we know that length is less than 65536.
292
  We keep a separate version for that range because it's widely used in
293
  libmysql.
294
482 by Brian Aker
Remove uint.
295
  uint32_t is used as agrument type because of MySQL type conventions:
296
  - uint32_t for 0..65536
1 by brian
clean slate
297
  - ulong for 0..4294967296
151 by Brian Aker
Ulonglong to uint64_t
298
  - uint64_t for bigger numbers.
1 by brian
clean slate
299
*/
300
482 by Brian Aker
Remove uint.
301
static unsigned char *net_store_length_fast(unsigned char *packet, uint32_t length)
1 by brian
clean slate
302
{
303
  if (length < 251)
304
  {
481 by Brian Aker
Remove all of uchar.
305
    *packet=(unsigned char) length;
1 by brian
clean slate
306
    return packet+1;
307
  }
308
  *packet++=252;
628 by Brian Aker
Collection of dead code removal
309
  int2store(packet,(uint32_t) length);
310
1 by brian
clean slate
311
  return packet+2;
312
}
313
314
/**
315
  Send the status of the current statement execution over network.
316
520.1.22 by Brian Aker
Second pass of thd cleanup
317
  @param  session   in fact, carries two parameters, NET for the transport and
1 by brian
clean slate
318
                Diagnostics_area as the source of status information.
319
320
  In MySQL, there are two types of SQL statements: those that return
321
  a result set and those that return status information only.
322
323
  If a statement returns a result set, it consists of 3 parts:
324
  - result set meta-data
325
  - variable number of result set rows (can be 0)
326
  - followed and terminated by EOF or ERROR packet
327
328
  Once the  client has seen the meta-data information, it always
329
  expects an EOF or ERROR to terminate the result set. If ERROR is
330
  received, the result set rows are normally discarded (this is up
331
  to the client implementation, libmysql at least does discard them).
332
  EOF, on the contrary, means "successfully evaluated the entire
333
  result set". Since we don't know how many rows belong to a result
334
  set until it's evaluated, EOF/ERROR is the indicator of the end
335
  of the row stream. Note, that we can not buffer result set rows
336
  on the server -- there may be an arbitrary number of rows. But
337
  we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
338
  delay sending it till the very end of execution (here), to be able to
339
  change EOF to an ERROR if commit failed or some other error occurred
340
  during the last cleanup steps taken after execution.
341
342
  A statement that does not return a result set doesn't send result
343
  set meta-data either. Instead it returns one of:
344
  - OK packet
345
  - ERROR packet.
346
  Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
347
  packet is "buffered" in the diagnostics area and sent to the client
348
  in the end of statement.
349
350
  @pre  The diagnostics area is assigned or disabled. It can not be empty
351
        -- we assume that every SQL statement or COM_* command
352
        generates OK, ERROR, or EOF status.
353
354
  @post The status information is encoded to protocol format and sent to the
355
        client.
356
357
  @return We conventionally return void, since the only type of error
358
          that can happen here is a NET (transport) error, and that one
359
          will become visible when we attempt to read from the NET the
360
          next command.
361
          Diagnostics_area::is_sent is set for debugging purposes only.
362
*/
363
520.1.22 by Brian Aker
Second pass of thd cleanup
364
void net_end_statement(Session *session)
1 by brian
clean slate
365
{
520.1.22 by Brian Aker
Second pass of thd cleanup
366
  assert(! session->main_da.is_sent);
1 by brian
clean slate
367
368
  /* Can not be true, but do not take chances in production. */
520.1.22 by Brian Aker
Second pass of thd cleanup
369
  if (session->main_da.is_sent)
1 by brian
clean slate
370
    return;
371
520.1.22 by Brian Aker
Second pass of thd cleanup
372
  switch (session->main_da.status()) {
1 by brian
clean slate
373
  case Diagnostics_area::DA_ERROR:
374
    /* The query failed, send error to log and abort bootstrap. */
520.1.22 by Brian Aker
Second pass of thd cleanup
375
    net_send_error(session,
376
                   session->main_da.sql_errno(),
377
                   session->main_da.message());
1 by brian
clean slate
378
    break;
379
  case Diagnostics_area::DA_EOF:
520.1.22 by Brian Aker
Second pass of thd cleanup
380
    net_send_eof(session,
381
                 session->main_da.server_status(),
382
                 session->main_da.total_warn_count());
1 by brian
clean slate
383
    break;
384
  case Diagnostics_area::DA_OK:
520.1.22 by Brian Aker
Second pass of thd cleanup
385
    net_send_ok(session,
386
                session->main_da.server_status(),
387
                session->main_da.total_warn_count(),
388
                session->main_da.affected_rows(),
389
                session->main_da.last_insert_id(),
390
                session->main_da.message());
1 by brian
clean slate
391
    break;
392
  case Diagnostics_area::DA_DISABLED:
393
    break;
394
  case Diagnostics_area::DA_EMPTY:
395
  default:
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
396
    assert(0);
520.1.22 by Brian Aker
Second pass of thd cleanup
397
    net_send_ok(session, session->server_status, session->total_warn_count,
1 by brian
clean slate
398
                0, 0, NULL);
399
    break;
400
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
401
  session->main_da.is_sent= true;
1 by brian
clean slate
402
}
403
404
405
/****************************************************************************
406
  Functions used by the protocol functions (like net_send_ok) to store
407
  strings and numbers in the header result packet.
408
****************************************************************************/
409
410
/* The following will only be used for short strings < 65K */
411
481 by Brian Aker
Remove all of uchar.
412
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
1 by brian
clean slate
413
{
414
  to=net_store_length_fast(to,length);
415
  memcpy(to,from,length);
416
  return to+length;
417
}
418
481 by Brian Aker
Remove all of uchar.
419
unsigned char *net_store_data(unsigned char *to,int32_t from)
1 by brian
clean slate
420
{
421
  char buff[20];
482 by Brian Aker
Remove uint.
422
  uint32_t length=(uint) (int10_to_str(from,buff,10)-buff);
1 by brian
clean slate
423
  to=net_store_length_fast(to,length);
424
  memcpy(to,buff,length);
425
  return to+length;
426
}
427
481 by Brian Aker
Remove all of uchar.
428
unsigned char *net_store_data(unsigned char *to,int64_t from)
1 by brian
clean slate
429
{
430
  char buff[22];
482 by Brian Aker
Remove uint.
431
  uint32_t length=(uint) (int64_t10_to_str(from,buff,10)-buff);
1 by brian
clean slate
432
  to=net_store_length_fast(to,length);
433
  memcpy(to,buff,length);
434
  return to+length;
435
}
436
437
438
/*****************************************************************************
439
  Default Protocol functions
440
*****************************************************************************/
441
520.1.22 by Brian Aker
Second pass of thd cleanup
442
void Protocol::init(Session *session_arg)
1 by brian
clean slate
443
{
520.1.22 by Brian Aker
Second pass of thd cleanup
444
  session=session_arg;
445
  packet= &session->packet;
446
  convert= &session->convert_buffer;
1 by brian
clean slate
447
}
448
449
/**
450
  Finish the result set with EOF packet, as is expected by the client,
451
  if there is an error evaluating the next row and a continue handler
452
  for the error.
453
*/
454
520.1.22 by Brian Aker
Second pass of thd cleanup
455
void Protocol::end_partial_result_set(Session *session)
1 by brian
clean slate
456
{
520.1.22 by Brian Aker
Second pass of thd cleanup
457
  net_send_eof(session, session->server_status, 0 /* no warnings, we're inside SP */);
1 by brian
clean slate
458
}
459
460
461
bool Protocol::flush()
462
{
520.1.22 by Brian Aker
Second pass of thd cleanup
463
  return net_flush(&session->net);
1 by brian
clean slate
464
}
465
466
467
/**
468
  Send name and type of result to client.
469
470
  Sum fields has table name empty and field_name.
471
520.1.21 by Brian Aker
THD -> Session rename
472
  @param Session		Thread data object
1 by brian
clean slate
473
  @param list	        List of items to send to client
474
  @param flag	        Bit mask with the following functions:
475
                        - 1 send number of rows
476
                        - 2 send default values
477
                        - 4 don't write eof packet
478
479
  @retval
480
    0	ok
481
  @retval
482
    1	Error  (Note that in this case the error is not sent to the
483
    client)
484
*/
482 by Brian Aker
Remove uint.
485
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
1 by brian
clean slate
486
{
487
  List_iterator_fast<Item> it(*list);
488
  Item *item;
481 by Brian Aker
Remove all of uchar.
489
  unsigned char buff[80];
1 by brian
clean slate
490
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
520.1.22 by Brian Aker
Second pass of thd cleanup
491
  Protocol_text prot(session);
1 by brian
clean slate
492
  String *local_packet= prot.storage_packet();
520.1.22 by Brian Aker
Second pass of thd cleanup
493
  const CHARSET_INFO * const session_charset= session->variables.character_set_results;
1 by brian
clean slate
494
495
  if (flags & SEND_NUM_ROWS)
496
  {				// Packet with number of elements
481 by Brian Aker
Remove all of uchar.
497
    unsigned char *pos= net_store_length(buff, list->elements);
520.1.22 by Brian Aker
Second pass of thd cleanup
498
    (void) my_net_write(&session->net, buff, (size_t) (pos-buff));
1 by brian
clean slate
499
  }
500
501
  while ((item=it++))
502
  {
503
    char *pos;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
504
    const CHARSET_INFO * const cs= system_charset_info;
1 by brian
clean slate
505
    Send_field field;
506
    item->make_field(&field);
507
508
    prot.prepare_for_resend();
509
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
510
520.1.22 by Brian Aker
Second pass of thd cleanup
511
    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
512
        prot.store(field.db_name, (uint) strlen(field.db_name),
520.1.22 by Brian Aker
Second pass of thd cleanup
513
                   cs, session_charset) ||
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
514
        prot.store(field.table_name, (uint) strlen(field.table_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.org_table_name, (uint) strlen(field.org_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.col_name, (uint) strlen(field.col_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.org_col_name, (uint) strlen(field.org_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
        local_packet->realloc(local_packet->length()+12))
523
      goto err;
524
525
    /* Store fixed length fields */
526
    pos= (char*) local_packet->ptr()+local_packet->length();
527
    *pos++= 12;				// Length of packed fields
520.1.22 by Brian Aker
Second pass of thd cleanup
528
    if (item->collation.collation == &my_charset_bin || session_charset == NULL)
1 by brian
clean slate
529
    {
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
530
      /* No conversion */
531
      int2store(pos, field.charsetnr);
532
      int4store(pos+2, field.length);
1 by brian
clean slate
533
    }
534
    else
535
    {
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
536
      /* With conversion */
482 by Brian Aker
Remove uint.
537
      uint32_t max_char_len;
520.1.22 by Brian Aker
Second pass of thd cleanup
538
      int2store(pos, session_charset->number);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
539
      /*
540
        For TEXT/BLOB columns, field_length describes the maximum data
541
        length in bytes. There is no limit to the number of characters
542
        that a TEXT column can store, as long as the data fits into
543
        the designated space.
544
        For the rest of textual columns, field_length is evaluated as
545
        char_count * mbmaxlen, where character count is taken from the
546
        definition of the column. In other words, the maximum number
547
        of characters here is limited by the column definition.
548
      */
549
      max_char_len= field.length / item->collation.collation->mbmaxlen;
520.1.22 by Brian Aker
Second pass of thd cleanup
550
      int4store(pos+2, max_char_len * session_charset->mbmaxlen);
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
551
    }
552
    pos[6]= field.type;
553
    int2store(pos+7,field.flags);
554
    pos[9]= (char) field.decimals;
555
    pos[10]= 0;				// For the future
556
    pos[11]= 0;				// For the future
557
    pos+= 12;
1 by brian
clean slate
558
559
    local_packet->length((uint) (pos - local_packet->ptr()));
560
    if (flags & SEND_DEFAULTS)
561
      item->send(&prot, &tmp);			// Send default value
562
    if (prot.write())
563
      break;					/* purecov: inspected */
564
  }
565
566
  if (flags & SEND_EOF)
567
  {
568
    /*
520.1.22 by Brian Aker
Second pass of thd cleanup
569
      Mark the end of meta-data result set, and store session->server_status,
1 by brian
clean slate
570
      to show that there is no cursor.
571
      Send no warning information, as it will be sent at statement end.
572
    */
520.1.22 by Brian Aker
Second pass of thd cleanup
573
    write_eof_packet(session, &session->net, session->server_status, session->total_warn_count);
1 by brian
clean slate
574
  }
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
575
  return(prepare_for_send(list));
1 by brian
clean slate
576
577
err:
578
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
579
             MYF(0));	/* purecov: inspected */
51.1.76 by Jay Pipes
Standardized TRUE/FALSE, removed/replaced DBUG symbols
580
  return(1);				/* purecov: inspected */
1 by brian
clean slate
581
}
582
583
584
bool Protocol::write()
585
{
520.1.22 by Brian Aker
Second pass of thd cleanup
586
  return(my_net_write(&session->net, (unsigned char*) packet->ptr(),
1 by brian
clean slate
587
                           packet->length()));
588
}
589
590
591
/**
592
  Send \\0 end terminated string.
593
461 by Monty Taylor
Removed NullS. bu-bye.
594
  @param from	NULL or \\0 terminated string
1 by brian
clean slate
595
596
  @note
597
    In most cases one should use store(from, length) instead of this function
598
599
  @retval
600
    0		ok
601
  @retval
602
    1		error
603
*/
604
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
605
bool Protocol::store(const char *from, const CHARSET_INFO * const cs)
1 by brian
clean slate
606
{
607
  if (!from)
608
    return store_null();
482 by Brian Aker
Remove uint.
609
  uint32_t length= strlen(from);
1 by brian
clean slate
610
  return store(from, length, cs);
611
}
612
613
614
/**
615
  Send a set of strings as one long string with ',' in between.
616
*/
617
618
bool Protocol::store(I_List<i_string>* str_list)
619
{
620
  char buf[256];
621
  String tmp(buf, sizeof(buf), &my_charset_bin);
205 by Brian Aker
uint32 -> uin32_t
622
  uint32_t len;
1 by brian
clean slate
623
  I_List_iterator<i_string> it(*str_list);
624
  i_string* s;
625
626
  tmp.length(0);
627
  while ((s=it++))
628
  {
629
    tmp.append(s->ptr);
630
    tmp.append(',');
631
  }
632
  if ((len= tmp.length()))
633
    len--;					// Remove last ','
634
  return store((char*) tmp.ptr(), len,  tmp.charset());
635
}
636
637
584.1.14 by Monty Taylor
Removed field.h from common_includes.
638
bool Protocol::store(String *str)
639
{
640
  return store((char*) str->ptr(), str->length(), str->charset());
641
}
642
643
void Protocol::free()
644
{
645
  packet->free();
646
}
647
648
1 by brian
clean slate
649
/****************************************************************************
650
  Functions to handle the simple (default) protocol where everything is
651
  This protocol is the one that is used by default between the MySQL server
652
  and client when you are not using prepared statements.
653
654
  All data are sent as 'packed-string-length' followed by 'string-data'
655
****************************************************************************/
656
657
void Protocol_text::prepare_for_resend()
658
{
659
  packet->length(0);
660
}
661
662
bool Protocol_text::store_null()
663
{
664
  char buff[1];
665
  buff[0]= (char)251;
666
  return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
667
}
668
669
670
/**
671
  Auxilary function to convert string to the given character set
672
  and store in network buffer.
673
*/
674
675
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.
676
                                const CHARSET_INFO * const fromcs,
677
								const CHARSET_INFO * const tocs)
1 by brian
clean slate
678
{
679
  /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
680
  if (tocs && !my_charset_same(fromcs, tocs) &&
681
      fromcs != &my_charset_bin &&
682
      tocs != &my_charset_bin)
683
  {
684
    /* Store with conversion */
481 by Brian Aker
Remove all of uchar.
685
    return net_store_data((unsigned char*) from, length, fromcs, tocs);
1 by brian
clean slate
686
  }
687
  /* Store without conversion */
481 by Brian Aker
Remove all of uchar.
688
  return net_store_data((unsigned char*) from, length);
1 by brian
clean slate
689
}
690
691
692
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.
693
                          const CHARSET_INFO * const fromcs,
694
						  const CHARSET_INFO * const tocs)
1 by brian
clean slate
695
{
696
  return store_string_aux(from, length, fromcs, tocs);
697
}
698
699
700
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.
701
                          const CHARSET_INFO * const fromcs)
1 by brian
clean slate
702
{
520.1.22 by Brian Aker
Second pass of thd cleanup
703
  const CHARSET_INFO * const tocs= this->session->variables.character_set_results;
1 by brian
clean slate
704
  return store_string_aux(from, length, fromcs, tocs);
705
}
706
707
152 by Brian Aker
longlong replacement
708
bool Protocol_text::store_tiny(int64_t from)
1 by brian
clean slate
709
{
710
  char buff[20];
481 by Brian Aker
Remove all of uchar.
711
  return net_store_data((unsigned char*) buff,
1 by brian
clean slate
712
			(size_t) (int10_to_str((int) from, buff, -10) - buff));
713
}
714
715
152 by Brian Aker
longlong replacement
716
bool Protocol_text::store_short(int64_t from)
1 by brian
clean slate
717
{
718
  char buff[20];
481 by Brian Aker
Remove all of uchar.
719
  return net_store_data((unsigned char*) buff,
1 by brian
clean slate
720
			(size_t) (int10_to_str((int) from, buff, -10) -
721
                                  buff));
722
}
723
724
152 by Brian Aker
longlong replacement
725
bool Protocol_text::store_long(int64_t from)
1 by brian
clean slate
726
{
727
  char buff[20];
481 by Brian Aker
Remove all of uchar.
728
  return net_store_data((unsigned char*) buff,
1 by brian
clean slate
729
			(size_t) (int10_to_str((long int)from, buff,
730
                                               (from <0)?-10:10)-buff));
731
}
732
733
152 by Brian Aker
longlong replacement
734
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
1 by brian
clean slate
735
{
736
  char buff[22];
481 by Brian Aker
Remove all of uchar.
737
  return net_store_data((unsigned char*) buff,
152 by Brian Aker
longlong replacement
738
			(size_t) (int64_t10_to_str(from,buff,
1 by brian
clean slate
739
                                                    unsigned_flag ? 10 : -10)-
740
                                  buff));
741
}
742
743
744
bool Protocol_text::store_decimal(const my_decimal *d)
745
{
746
  char buff[DECIMAL_MAX_STR_LENGTH];
747
  String str(buff, sizeof(buff), &my_charset_bin);
748
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
481 by Brian Aker
Remove all of uchar.
749
  return net_store_data((unsigned char*) str.ptr(), str.length());
1 by brian
clean slate
750
}
751
752
205 by Brian Aker
uint32 -> uin32_t
753
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
1 by brian
clean slate
754
{
520.1.22 by Brian Aker
Second pass of thd cleanup
755
  buffer->set_real((double) from, decimals, session->charset());
481 by Brian Aker
Remove all of uchar.
756
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
1 by brian
clean slate
757
}
758
759
205 by Brian Aker
uint32 -> uin32_t
760
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
1 by brian
clean slate
761
{
520.1.22 by Brian Aker
Second pass of thd cleanup
762
  buffer->set_real(from, decimals, session->charset());
481 by Brian Aker
Remove all of uchar.
763
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
1 by brian
clean slate
764
}
765
766
767
bool Protocol_text::store(Field *field)
768
{
769
  if (field->is_null())
770
    return store_null();
771
  char buff[MAX_FIELD_WIDTH];
772
  String str(buff,sizeof(buff), &my_charset_bin);
520.1.22 by Brian Aker
Second pass of thd cleanup
773
  const CHARSET_INFO * const tocs= this->session->variables.character_set_results;
1 by brian
clean slate
774
775
  field->val_str(&str);
776
777
  return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
778
}
779
780
781
/**
782
  @todo
783
    Second_part format ("%06") needs to change when 
784
    we support 0-6 decimals for time.
785
*/
786
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
787
bool Protocol_text::store(DRIZZLE_TIME *tm)
1 by brian
clean slate
788
{
789
  char buff[40];
482 by Brian Aker
Remove uint.
790
  uint32_t length;
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
791
  length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
1 by brian
clean slate
792
			   (int) tm->year,
793
			   (int) tm->month,
794
			   (int) tm->day,
795
			   (int) tm->hour,
796
			   (int) tm->minute,
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
797
			   (int) tm->second);
1 by brian
clean slate
798
  if (tm->second_part)
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
799
    length+= sprintf(buff+length, ".%06d",
800
                                     (int)tm->second_part);
481 by Brian Aker
Remove all of uchar.
801
  return net_store_data((unsigned char*) buff, length);
1 by brian
clean slate
802
}
803
804
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
805
bool Protocol_text::store_date(DRIZZLE_TIME *tm)
1 by brian
clean slate
806
{
807
  char buff[MAX_DATE_STRING_REP_LENGTH];
808
  size_t length= my_date_to_str(tm, buff);
481 by Brian Aker
Remove all of uchar.
809
  return net_store_data((unsigned char*) buff, length);
1 by brian
clean slate
810
}
811
812
813
/**
814
  @todo 
815
    Second_part format ("%06") needs to change when 
816
    we support 0-6 decimals for time.
817
*/
818
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
819
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
1 by brian
clean slate
820
{
821
  char buff[40];
482 by Brian Aker
Remove uint.
822
  uint32_t length;
823
  uint32_t day= (tm->year || tm->month) ? 0 : tm->day;
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
824
  length= sprintf(buff, "%s%02ld:%02d:%02d",
1 by brian
clean slate
825
			   tm->neg ? "-" : "",
826
			   (long) day*24L+(long) tm->hour,
827
			   (int) tm->minute,
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
828
			   (int) tm->second);
1 by brian
clean slate
829
  if (tm->second_part)
171.1.1 by Patrick Galbraith
Dar, I forgot to commit this earlier.
830
    length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
481 by Brian Aker
Remove all of uchar.
831
  return net_store_data((unsigned char*) buff, length);
1 by brian
clean slate
832
}
833