~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/oldlibdrizzle/oldlibdrizzle.cc

  • Committer: Monty Taylor
  • Date: 2009-04-09 05:35:58 UTC
  • mfrom: (984 merge)
  • mto: (992.1.1 mordred)
  • mto: This revision was merged to the branch mainline in revision 986.
  • Revision ID: mordred@inaugust.com-20090409053558-qi1x0zzsgf1d8f1p
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 */
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; version 2 of the License.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 */
15
19
 
16
20
/**
17
21
  @file
19
23
  Low level functions for storing data to be send to the MySQL client.
20
24
  The actual communction is handled by the net_xxx functions in net_serv.cc
21
25
*/
 
26
 
22
27
#include <drizzled/server_includes.h>
23
28
#include <drizzled/error.h>
24
29
#include <drizzled/sql_state.h>
25
 
#include <libdrizzleclient/pack.h>
26
 
#include <libdrizzleclient/errmsg.h>
27
30
#include <drizzled/protocol.h>
28
31
#include <drizzled/session.h>
29
32
#include <drizzled/data_home.h>
 
33
#include "pack.h"
 
34
#include "errmsg.h"
 
35
#include "oldlibdrizzle.h"
30
36
 
31
37
/*
32
38
  Function called by drizzleclient_net_init() to set some check variables
33
39
*/
34
40
 
35
 
extern "C" {
36
 
  void drizzleclient_net_local_init(NET *net)
37
 
  {
38
 
    net->max_packet= (uint32_t) global_system_variables.net_buffer_length;
39
 
 
40
 
    drizzleclient_net_set_read_timeout(net,
41
 
                            (uint32_t)global_system_variables.net_read_timeout);
42
 
    drizzleclient_net_set_write_timeout(net,
43
 
                           (uint32_t)global_system_variables.net_write_timeout);
44
 
 
45
 
    net->retry_count=  (uint32_t) global_system_variables.net_retry_count;
46
 
    net->max_packet_size= cmax(global_system_variables.net_buffer_length,
47
 
                               global_system_variables.max_allowed_packet);
48
 
  }
49
 
}
50
 
 
51
41
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
52
42
 
53
43
static void write_eof_packet(Session *session, NET *net,
54
44
                             uint32_t server_status, uint32_t total_warn_count);
55
45
 
56
 
bool Protocol::io_ok()
 
46
bool ProtocolOldLibdrizzle::isConnected()
57
47
{
58
48
  return net.vio != 0;
59
49
}
60
50
 
61
 
void Protocol::set_read_timeout(uint32_t timeout)
 
51
void ProtocolOldLibdrizzle::setReadTimeout(uint32_t timeout)
62
52
{
63
53
  drizzleclient_net_set_read_timeout(&net, timeout);
64
54
}
65
55
 
66
 
void Protocol::set_write_timeout(uint32_t timeout)
 
56
void ProtocolOldLibdrizzle::setWriteTimeout(uint32_t timeout)
67
57
{
68
58
  drizzleclient_net_set_write_timeout(&net, timeout);
69
59
}
70
60
 
71
 
void Protocol::set_retry_count(uint32_t count)
 
61
void ProtocolOldLibdrizzle::setRetryCount(uint32_t count)
72
62
{
73
63
  net.retry_count=count;
74
64
}
75
65
 
76
 
void Protocol::set_error(char error)
 
66
void ProtocolOldLibdrizzle::setError(char error)
77
67
{
78
68
  net.error= error;
79
69
}
80
70
 
81
 
bool Protocol::have_error(void)
 
71
bool ProtocolOldLibdrizzle::haveError(void)
82
72
{
83
73
  return net.error || net.vio == 0;
84
74
}
85
75
 
86
 
bool Protocol::was_aborted(void)
 
76
bool ProtocolOldLibdrizzle::wasAborted(void)
87
77
{
88
78
  return net.error && net.vio != 0;
89
79
}
90
80
 
91
 
bool Protocol::have_more_data(void)
 
81
bool ProtocolOldLibdrizzle::haveMoreData(void)
92
82
{
93
83
  return drizzleclient_net_more_data(&net);
94
84
}
95
85
 
96
 
bool Protocol::have_compression(void)
97
 
{
98
 
  return net.compress;
99
 
}
100
 
 
101
 
void Protocol::enable_compression(void)
 
86
void ProtocolOldLibdrizzle::enableCompression(void)
102
87
{
103
88
  net.compress= true;
104
89
}
105
90
 
106
 
bool Protocol::is_reading(void)
 
91
bool ProtocolOldLibdrizzle::isReading(void)
107
92
{
108
93
  return net.reading_or_writing == 1;
109
94
}
110
95
 
111
 
bool Protocol::is_writing(void)
 
96
bool ProtocolOldLibdrizzle::isWriting(void)
112
97
{
113
98
  return net.reading_or_writing == 2;
114
99
}
115
100
 
116
 
/*
117
 
 * To disable results we set net.vio to 0.
118
 
 */
119
 
 
120
 
void Protocol::disable_results(void)
121
 
{
122
 
  save_vio= net.vio;
123
 
  net.vio= 0;
124
 
}
125
 
 
126
 
void Protocol::enable_results(void)
127
 
{
128
 
  net.vio= save_vio;
129
 
}
130
 
 
131
 
 
132
 
bool Protocol::net_store_data(const unsigned char *from, size_t length)
 
101
bool ProtocolOldLibdrizzle::netStoreData(const unsigned char *from, size_t length)
133
102
{
134
103
  size_t packet_length= packet->length();
135
104
  /*
146
115
}
147
116
 
148
117
 
149
 
 
150
 
 
151
118
/*
152
 
  net_store_data() - extended version with character set conversion.
 
119
  netStoreData() - extended version with character set conversion.
153
120
 
154
121
  It is optimized for short strings whose length after
155
122
  conversion is garanteed to be less than 251, which accupies
160
127
  because column, table, database names fit into this limit.
161
128
*/
162
129
 
163
 
bool Protocol::net_store_data(const unsigned char *from, size_t length,
 
130
bool ProtocolOldLibdrizzle::netStoreData(const unsigned char *from, size_t length,
164
131
                              const CHARSET_INFO * const from_cs,
165
 
                                                          const CHARSET_INFO * const to_cs)
 
132
                              const CHARSET_INFO * const to_cs)
166
133
{
167
134
  uint32_t dummy_errors;
168
135
  /* Calculate maxumum possible result length */
182
149
    */
183
150
    return (convert->copy((const char*) from, length, from_cs,
184
151
                          to_cs, &dummy_errors) ||
185
 
            net_store_data((const unsigned char*) convert->ptr(), convert->length()));
 
152
            netStoreData((const unsigned char*) convert->ptr(), convert->length()));
186
153
  }
187
154
 
188
155
  size_t packet_length= packet->length();
209
176
  The ok packet has the following structure:
210
177
 
211
178
  - 0               : Marker (1 byte)
212
 
  - affected_rows       : Stored in 1-9 bytes
213
 
  - id          : Stored in 1-9 bytes
214
 
  - server_status       : Copy of session->server_status;  Can be used by client
 
179
  - affected_rows    : Stored in 1-9 bytes
 
180
  - id        : Stored in 1-9 bytes
 
181
  - server_status    : Copy of session->server_status;  Can be used by client
215
182
  to check if we are inside an transaction.
216
183
  New in 4.0 protocol
217
 
  - warning_count       : Stored in 2 bytes; New in 4.1 protocol
218
 
  - message             : Stored as packed length (1-9 bytes) + message.
 
184
  - warning_count    : Stored in 2 bytes; New in 4.1 protocol
 
185
  - message        : Stored as packed length (1-9 bytes) + message.
219
186
  Is not stored if no message.
220
187
 
221
 
  @param session                   Thread handler
222
 
  @param affected_rows     Number of rows changed by statement
223
 
  @param id                Auto_increment id for first row (if used)
224
 
  @param message           Message to send to the client (Used by mysql_status)
 
188
  @param session           Thread handler
 
189
  @param affected_rows       Number of rows changed by statement
 
190
  @param id           Auto_increment id for first row (if used)
 
191
  @param message       Message to send to the client (Used by mysql_status)
225
192
*/
226
193
 
227
 
static void
228
 
net_send_ok(Session *session, NET *net,
229
 
            uint32_t server_status, uint32_t total_warn_count,
230
 
            ha_rows affected_rows, uint64_t id, const char *message)
 
194
void ProtocolOldLibdrizzle::sendOK()
231
195
{
232
196
  unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
 
197
  const char *message= NULL;
 
198
  uint32_t tmp;
233
199
 
234
 
  if (!net->vio)        // hack for re-parsing queries
 
200
  if (!net.vio)    // hack for re-parsing queries
235
201
  {
236
202
    return;
237
203
  }
238
204
 
239
 
  buff[0]=0;                                    // No fields
240
 
  pos=drizzleclient_net_store_length(buff+1,affected_rows);
241
 
  pos=drizzleclient_net_store_length(pos, id);
242
 
 
243
 
  int2store(pos, server_status);
244
 
  pos+=2;
 
205
  buff[0]=0;                    // No fields
 
206
  if (session->main_da.status() == Diagnostics_area::DA_OK)
 
207
  {
 
208
    pos=drizzleclient_net_store_length(buff+1,session->main_da.affected_rows());
 
209
    pos=drizzleclient_net_store_length(pos, session->main_da.last_insert_id());
 
210
    int2store(pos, session->main_da.server_status());
 
211
    pos+=2;
 
212
    tmp= cmin(session->main_da.total_warn_count(), (uint32_t)65535);
 
213
    message= session->main_da.message();
 
214
  }
 
215
  else
 
216
  {
 
217
    pos=drizzleclient_net_store_length(buff+1,0);
 
218
    pos=drizzleclient_net_store_length(pos, 0);
 
219
    int2store(pos, session->server_status);
 
220
    pos+=2;
 
221
    tmp= cmin(session->total_warn_count, (uint32_t)65535);
 
222
  }
245
223
 
246
224
  /* We can only return up to 65535 warnings in two bytes */
247
 
  uint32_t tmp= cmin(total_warn_count, (uint32_t)65535);
248
225
  int2store(pos, tmp);
249
226
  pos+= 2;
250
227
 
257
234
    memcpy(pos,(unsigned char*) message,length);
258
235
    pos+=length;
259
236
  }
260
 
  drizzleclient_net_write(net, buff, (size_t) (pos-buff));
261
 
  drizzleclient_net_flush(net);
 
237
  drizzleclient_net_write(&net, buff, (size_t) (pos-buff));
 
238
  drizzleclient_net_flush(&net);
262
239
 
263
240
  session->main_da.can_overwrite_status= false;
264
241
}
268
245
 
269
246
  The eof packet has the following structure:
270
247
 
271
 
  - 254 (DRIZZLE_PROTOCOL_NO_MORE_DATA) : Marker (1 byte)
272
 
  - warning_count       : Stored in 2 bytes; New in 4.1 protocol
273
 
  - status_flag : Stored in 2 bytes;
 
248
  - 254    (DRIZZLE_PROTOCOL_NO_MORE_DATA)    : Marker (1 byte)
 
249
  - warning_count    : Stored in 2 bytes; New in 4.1 protocol
 
250
  - status_flag    : Stored in 2 bytes;
274
251
  For flags like SERVER_MORE_RESULTS_EXISTS.
275
252
 
276
253
  Note that the warning count will not be sent if 'no_flush' is set as
277
254
  we don't want to report the warning count until all data is sent to the
278
255
  client.
279
 
 
280
 
  @param session                Thread handler
281
 
  @param no_flush       Set to 1 if there will be more data to the client,
282
 
                    like in send_fields().
283
256
*/
284
257
 
285
 
static void
286
 
net_send_eof(Session *session, NET *net, uint32_t server_status, uint32_t total_warn_count)
 
258
void ProtocolOldLibdrizzle::sendEOF()
287
259
{
288
260
  /* Set to true if no active vio, to work well in case of --init-file */
289
 
  if (net->vio != 0)
 
261
  if (net.vio != 0)
290
262
  {
291
263
    session->main_da.can_overwrite_status= true;
292
 
    write_eof_packet(session, net, server_status, total_warn_count);
293
 
    drizzleclient_net_flush(net);
 
264
    write_eof_packet(session, &net, session->main_da.server_status(),
 
265
                     session->main_da.total_warn_count());
 
266
    drizzleclient_net_flush(&net);
294
267
    session->main_da.can_overwrite_status= false;
295
268
  }
296
269
}
324
297
  drizzleclient_net_write(net, buff, 5);
325
298
}
326
299
 
327
 
void Protocol_text::send_error_packet(uint32_t sql_errno, const char *err)
 
300
void ProtocolOldLibdrizzle::sendError(uint32_t sql_errno, const char *err)
328
301
{
329
302
  uint32_t length;
330
303
  /*
332
305
  */
333
306
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
334
307
 
 
308
  assert(sql_errno);
 
309
  assert(err && err[0]);
 
310
 
 
311
  /*
 
312
    It's one case when we can push an error even though there
 
313
    is an OK or EOF already.
 
314
  */
 
315
  session->main_da.can_overwrite_status= true;
 
316
 
 
317
  /* Abort multi-result sets */
 
318
  session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
 
319
 
 
320
  /**
 
321
    Send a error string to client.
 
322
 
 
323
    For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
 
324
    critical that every error that can be intercepted is issued in one
 
325
    place only, my_message_sql.
 
326
  */
 
327
 
335
328
  if (net.vio == 0)
336
329
  {
337
330
    return;
352
345
  err= (char*) buff;
353
346
 
354
347
  drizzleclient_net_write_command(&net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
355
 
  return;
356
 
}
357
 
 
358
 
/**
359
 
  Send a error string to client.
360
 
 
361
 
  Design note:
362
 
  net_printf_error and net_send_error are low-level functions
363
 
  that shall be used only when a new connection is being
364
 
  established or at server startup.
365
 
 
366
 
  For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
367
 
  critical that every error that can be intercepted is issued in one
368
 
  place only, my_message_sql.
369
 
*/
370
 
void Protocol_text::send_error(uint32_t sql_errno, const char *err)
371
 
{
372
 
  assert(sql_errno);
373
 
  assert(err && err[0]);
374
 
 
375
 
  /*
376
 
    It's one case when we can push an error even though there
377
 
    is an OK or EOF already.
378
 
  */
379
 
  session->main_da.can_overwrite_status= true;
380
 
 
381
 
  /* Abort multi-result sets */
382
 
  session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
383
 
 
384
 
  send_error_packet(sql_errno, err);
385
348
 
386
349
  session->main_da.can_overwrite_status= false;
387
350
}
388
351
 
389
352
 
390
 
/**
391
 
  Send the status of the current statement execution over network.
392
 
 
393
 
  @param  session   in fact, carries two parameters, NET for the transport and
394
 
                Diagnostics_area as the source of status information.
395
 
 
396
 
  In MySQL, there are two types of SQL statements: those that return
397
 
  a result set and those that return status information only.
398
 
 
399
 
  If a statement returns a result set, it consists of 3 parts:
400
 
  - result set meta-data
401
 
  - variable number of result set rows (can be 0)
402
 
  - followed and terminated by EOF or ERROR packet
403
 
 
404
 
  Once the  client has seen the meta-data information, it always
405
 
  expects an EOF or ERROR to terminate the result set. If ERROR is
406
 
  received, the result set rows are normally discarded (this is up
407
 
  to the client implementation, libmysql at least does discard them).
408
 
  EOF, on the contrary, means "successfully evaluated the entire
409
 
  result set". Since we don't know how many rows belong to a result
410
 
  set until it's evaluated, EOF/ERROR is the indicator of the end
411
 
  of the row stream. Note, that we can not buffer result set rows
412
 
  on the server -- there may be an arbitrary number of rows. But
413
 
  we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
414
 
  delay sending it till the very end of execution (here), to be able to
415
 
  change EOF to an ERROR if commit failed or some other error occurred
416
 
  during the last cleanup steps taken after execution.
417
 
 
418
 
  A statement that does not return a result set doesn't send result
419
 
  set meta-data either. Instead it returns one of:
420
 
  - OK packet
421
 
  - ERROR packet.
422
 
  Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
423
 
  packet is "buffered" in the diagnostics area and sent to the client
424
 
  in the end of statement.
425
 
 
426
 
  @pre  The diagnostics area is assigned or disabled. It can not be empty
427
 
        -- we assume that every SQL statement or COM_* command
428
 
        generates OK, ERROR, or EOF status.
429
 
 
430
 
  @post The status information is encoded to protocol format and sent to the
431
 
        client.
432
 
 
433
 
  @return We conventionally return void, since the only type of error
434
 
          that can happen here is a NET (transport) error, and that one
435
 
          will become visible when we attempt to read from the NET the
436
 
          next command.
437
 
          Diagnostics_area::is_sent is set for debugging purposes only.
438
 
*/
439
 
 
440
 
void Protocol::end_statement()
 
353
ProtocolOldLibdrizzle::ProtocolOldLibdrizzle()
441
354
{
442
 
  assert(! session->main_da.is_sent);
443
 
 
444
 
  /* Can not be true, but do not take chances in production. */
445
 
  if (session->main_da.is_sent)
446
 
    return;
447
 
 
448
 
  switch (session->main_da.status()) {
449
 
  case Diagnostics_area::DA_ERROR:
450
 
    /* The query failed, send error to log and abort bootstrap. */
451
 
    send_error(session->main_da.sql_errno(),
452
 
               session->main_da.message());
453
 
    break;
454
 
  case Diagnostics_area::DA_EOF:
455
 
    net_send_eof(session, &net,
456
 
                 session->main_da.server_status(),
457
 
                 session->main_da.total_warn_count());
458
 
    break;
459
 
  case Diagnostics_area::DA_OK:
460
 
    net_send_ok(session, &net,
461
 
                session->main_da.server_status(),
462
 
                session->main_da.total_warn_count(),
463
 
                session->main_da.affected_rows(),
464
 
                session->main_da.last_insert_id(),
465
 
                session->main_da.message());
466
 
    break;
467
 
  case Diagnostics_area::DA_DISABLED:
468
 
    break;
469
 
  case Diagnostics_area::DA_EMPTY:
470
 
  default:
471
 
    //TODO: Something is being masked here by commenting this out
472
 
    //  assert(0);
473
 
    net_send_ok(session, &net, session->server_status, session->total_warn_count,
474
 
                0, 0, NULL);
475
 
    break;
476
 
  }
477
 
  session->main_da.is_sent= true;
 
355
  scramble[0]= 0;
 
356
  net.vio= 0;
478
357
}
479
358
 
480
 
 
481
 
/*****************************************************************************
482
 
  Default Protocol functions
483
 
*****************************************************************************/
484
 
 
485
 
void Protocol::init(Session *session_arg)
 
359
void ProtocolOldLibdrizzle::setSession(Session *session_arg)
486
360
{
487
 
  session=session_arg;
 
361
  session= session_arg;
488
362
  packet= &session->packet;
489
363
  convert= &session->convert_buffer;
490
 
  net.vio= 0;
491
 
}
492
 
 
493
 
 
494
 
bool Protocol::flush()
495
 
{
496
 
  return drizzleclient_net_flush(&net);
497
364
}
498
365
 
499
366
 
502
369
 
503
370
  Sum fields has table name empty and field_name.
504
371
 
505
 
  @param Session                Thread data object
506
 
  @param list           List of items to send to client
507
 
  @param flag           Bit mask with the following functions:
 
372
  @param Session        Thread data object
 
373
  @param list            List of items to send to client
 
374
  @param flag            Bit mask with the following functions:
508
375
                        - 1 send number of rows
509
376
                        - 2 send default values
510
377
                        - 4 don't write eof packet
511
378
 
512
379
  @retval
513
 
    0   ok
 
380
    0    ok
514
381
  @retval
515
 
    1   Error  (Note that in this case the error is not sent to the
 
382
    1    Error  (Note that in this case the error is not sent to the
516
383
    client)
517
384
*/
518
 
bool Protocol::send_fields(List<Item> *list, uint32_t flags)
 
385
bool ProtocolOldLibdrizzle::sendFields(List<Item> *list, uint32_t flags)
519
386
{
520
387
  List_iterator_fast<Item> it(*list);
521
388
  Item *item;
522
389
  unsigned char buff[80];
523
390
  String tmp((char*) buff,sizeof(buff),&my_charset_bin);
524
 
  String *local_packet= storage_packet();
525
 
  const CHARSET_INFO * const session_charset= default_charset_info;
526
391
 
527
392
  if (flags & SEND_NUM_ROWS)
528
 
  {                             // Packet with number of elements
 
393
  {                // Packet with number of elements
529
394
    unsigned char *pos= drizzleclient_net_store_length(buff, list->elements);
530
395
    (void) drizzleclient_net_write(&net, buff, (size_t) (pos-buff));
531
396
  }
537
402
    Send_field field;
538
403
    item->make_field(&field);
539
404
 
540
 
    prepare_for_resend();
541
 
 
542
 
 
543
 
    if (store(STRING_WITH_LEN("def"), cs, session_charset) ||
544
 
        store(field.db_name, (uint32_t) strlen(field.db_name),
545
 
                   cs, session_charset) ||
546
 
        store(field.table_name, (uint32_t) strlen(field.table_name),
547
 
                   cs, session_charset) ||
548
 
        store(field.org_table_name, (uint32_t) strlen(field.org_table_name),
549
 
                   cs, session_charset) ||
550
 
        store(field.col_name, (uint32_t) strlen(field.col_name),
551
 
                   cs, session_charset) ||
552
 
        store(field.org_col_name, (uint32_t) strlen(field.org_col_name),
553
 
                   cs, session_charset) ||
554
 
        local_packet->realloc(local_packet->length()+12))
 
405
    prepareForResend();
 
406
 
 
407
    if (store(STRING_WITH_LEN("def"), cs) ||
 
408
        store(field.db_name, cs) ||
 
409
        store(field.table_name, cs) ||
 
410
        store(field.org_table_name, cs) ||
 
411
        store(field.col_name, cs) ||
 
412
        store(field.org_col_name, cs) ||
 
413
        packet->realloc(packet->length()+12))
555
414
      goto err;
556
415
 
557
416
    /* Store fixed length fields */
558
 
    pos= (char*) local_packet->ptr()+local_packet->length();
559
 
    *pos++= 12;                         // Length of packed fields
560
 
    if (item->collation.collation == &my_charset_bin || session_charset == NULL)
 
417
    pos= (char*) packet->ptr()+packet->length();
 
418
    *pos++= 12;                // Length of packed fields
 
419
    if (item->collation.collation == &my_charset_bin)
561
420
    {
562
421
      /* No conversion */
563
422
      int2store(pos, field.charsetnr);
567
426
    {
568
427
      /* With conversion */
569
428
      uint32_t max_char_len;
570
 
      int2store(pos, session_charset->number);
 
429
      int2store(pos, cs->number);
571
430
      /*
572
431
        For TEXT/BLOB columns, field_length describes the maximum data
573
432
        length in bytes. There is no limit to the number of characters
579
438
        of characters here is limited by the column definition.
580
439
      */
581
440
      max_char_len= field.length / item->collation.collation->mbmaxlen;
582
 
      int4store(pos+2, max_char_len * session_charset->mbmaxlen);
 
441
      int4store(pos+2, max_char_len * cs->mbmaxlen);
583
442
    }
584
443
    pos[6]= field.type;
585
444
    int2store(pos+7,field.flags);
586
445
    pos[9]= (char) field.decimals;
587
 
    pos[10]= 0;                         // For the future
588
 
    pos[11]= 0;                         // For the future
 
446
    pos[10]= 0;                // For the future
 
447
    pos[11]= 0;                // For the future
589
448
    pos+= 12;
590
449
 
591
 
    local_packet->length((uint32_t) (pos - local_packet->ptr()));
 
450
    packet->length((uint32_t) (pos - packet->ptr()));
592
451
    if (flags & SEND_DEFAULTS)
593
 
      item->send(this, &tmp);                   // Send default value
 
452
      item->send(this, &tmp);            // Send default value
594
453
    if (write())
595
 
      break;                                    /* purecov: inspected */
 
454
      break;                    /* purecov: inspected */
596
455
  }
597
456
 
598
457
  if (flags & SEND_EOF)
604
463
    */
605
464
    write_eof_packet(session, &net, session->server_status, session->total_warn_count);
606
465
  }
607
 
  return(prepare_for_send(list));
 
466
 
 
467
  field_count= list->elements;
 
468
  return 0;
608
469
 
609
470
err:
610
471
  my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
611
 
             MYF(0));   /* purecov: inspected */
612
 
  return(1);                            /* purecov: inspected */
 
472
             MYF(0));    /* purecov: inspected */
 
473
  return 1;                /* purecov: inspected */
613
474
}
614
475
 
615
476
 
616
 
bool Protocol::write()
 
477
bool ProtocolOldLibdrizzle::write()
617
478
{
618
479
  return(drizzleclient_net_write(&net, (unsigned char*) packet->ptr(),
619
480
                           packet->length()));
620
481
}
621
482
 
622
 
 
623
 
/**
624
 
  Send \\0 end terminated string.
625
 
 
626
 
  @param from   NULL or \\0 terminated string
627
 
 
628
 
  @note
629
 
    In most cases one should use store(from, length) instead of this function
630
 
 
631
 
  @retval
632
 
    0           ok
633
 
  @retval
634
 
    1           error
635
 
*/
636
 
 
637
 
bool Protocol::store(const char *from, const CHARSET_INFO * const cs)
638
 
{
639
 
  if (!from)
640
 
    return store_null();
641
 
  uint32_t length= strlen(from);
642
 
  return store(from, length, cs);
643
 
}
644
 
 
645
 
 
646
 
/**
647
 
  Send a set of strings as one long string with ',' in between.
648
 
*/
649
 
 
650
 
bool Protocol::store(I_List<i_string>* str_list)
651
 
{
652
 
  char buf[256];
653
 
  String tmp(buf, sizeof(buf), &my_charset_bin);
654
 
  uint32_t len;
655
 
  I_List_iterator<i_string> it(*str_list);
656
 
  i_string* s;
657
 
 
658
 
  tmp.length(0);
659
 
  while ((s=it++))
660
 
  {
661
 
    tmp.append(s->ptr);
662
 
    tmp.append(',');
663
 
  }
664
 
  if ((len= tmp.length()))
665
 
    len--;                                      // Remove last ','
666
 
  return store((char*) tmp.ptr(), len,  tmp.charset());
667
 
}
668
 
 
669
 
 
670
 
bool Protocol::store(String *str)
671
 
{
672
 
  return store((char*) str->ptr(), str->length(), str->charset());
673
 
}
674
 
 
675
 
void Protocol::free()
 
483
void ProtocolOldLibdrizzle::free()
676
484
{
677
485
  packet->free();
678
486
}
679
487
 
680
488
 
681
 
/****************************************************************************
682
 
  Functions to handle the simple (default) protocol where everything is
683
 
  This protocol is the one that is used by default between the MySQL server
684
 
  and client when you are not using prepared statements.
685
 
 
686
 
  All data are sent as 'packed-string-length' followed by 'string-data'
687
 
****************************************************************************/
688
 
 
689
 
void Protocol_text::init_random(uint64_t seed1, uint64_t seed2)
 
489
void ProtocolOldLibdrizzle::setRandom(uint64_t seed1, uint64_t seed2)
690
490
{
691
 
  drizzleclient_randominit(&_rand, seed1, seed2);
 
491
  drizzleclient_randominit(&rand, seed1, seed2);
692
492
}
693
493
 
694
 
bool Protocol_text::init_file_descriptor(int fd)
 
494
bool ProtocolOldLibdrizzle::setFileDescriptor(int fd)
695
495
{
696
496
  if (drizzleclient_net_init_sock(&net, fd, 0))
697
497
    return true;
698
498
  return false;
699
499
}
700
500
 
701
 
int Protocol_text::file_descriptor(void)
 
501
int ProtocolOldLibdrizzle::fileDescriptor(void)
702
502
{
703
503
  return drizzleclient_net_get_sd(&net);
704
504
}
705
505
 
706
 
bool Protocol_text::authenticate()
 
506
bool ProtocolOldLibdrizzle::authenticate()
707
507
{
708
508
  bool connection_is_valid;
709
509
 
711
511
  drizzleclient_net_set_read_timeout(&net, connect_timeout);
712
512
  drizzleclient_net_set_write_timeout(&net, connect_timeout);
713
513
 
714
 
  connection_is_valid= _check_connection();
715
 
  end_statement();
 
514
  connection_is_valid= checkConnection();
716
515
 
717
 
  if (!connection_is_valid)
 
516
  if (connection_is_valid)
 
517
    sendOK();
 
518
  else
 
519
  {
 
520
    sendError(session->main_da.sql_errno(), session->main_da.message());
718
521
    return false;
 
522
  }
719
523
 
720
524
  /* Connect completed, set read/write timeouts back to default */
721
525
  drizzleclient_net_set_read_timeout(&net,
725
529
  return true;
726
530
}
727
531
 
728
 
bool Protocol_text::read_command(char **l_packet, uint32_t *packet_length)
 
532
bool ProtocolOldLibdrizzle::readCommand(char **l_packet, uint32_t *packet_length)
729
533
{
730
534
  /*
731
535
    This thread will do a blocking read from the client which
736
540
  drizzleclient_net_set_read_timeout(&net,
737
541
                                     session->variables.net_wait_timeout);
738
542
 
739
 
  /*
740
 
    XXX: this code is here only to clear possible errors of init_connect.
741
 
    Consider moving to init_connect() instead.
742
 
  */
743
 
  session->clear_error();                    // Clear error message
 
543
  session->clear_error();
744
544
  session->main_da.reset_diagnostics_area();
745
545
 
746
546
  net.pkt_nr=0;
752
552
 
753
553
    if(net.last_errno== CR_NET_PACKET_TOO_LARGE)
754
554
      my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
755
 
    /* Assert is invalid for dirty connection shutdown
756
 
     *     assert(session->is_error());
757
 
     */
758
 
    end_statement();
 
555
    if (session->main_da.status() == Diagnostics_area::DA_ERROR)
 
556
      sendError(session->main_da.sql_errno(), session->main_da.message());
 
557
    else
 
558
      session->protocol->sendOK();
759
559
 
760
560
    if (net.error != 3)
761
561
      return false;                       // We have to close it.
792
592
  return true;
793
593
}
794
594
 
795
 
void Protocol_text::close(void)
 
595
void ProtocolOldLibdrizzle::close(void)
796
596
{
797
597
  if (net.vio)
798
598
  { 
801
601
  }
802
602
}
803
603
 
804
 
void Protocol_text::prepare_for_resend()
 
604
void ProtocolOldLibdrizzle::prepareForResend()
805
605
{
806
606
  packet->length(0);
807
607
}
808
608
 
809
 
bool Protocol_text::store_null()
 
609
bool ProtocolOldLibdrizzle::store(void)
810
610
{
811
611
  char buff[1];
812
612
  buff[0]= (char)251;
819
619
  and store in network buffer.
820
620
*/
821
621
 
822
 
bool Protocol::store_string_aux(const char *from, size_t length,
823
 
                                const CHARSET_INFO * const fromcs,
824
 
                                                                const CHARSET_INFO * const tocs)
 
622
bool ProtocolOldLibdrizzle::storeString(const char *from, size_t length,
 
623
                                        const CHARSET_INFO * const fromcs,
 
624
                                        const CHARSET_INFO * const tocs)
825
625
{
826
626
  /* 'tocs' is set 0 when client issues SET character_set_results=NULL */
827
627
  if (tocs && !my_charset_same(fromcs, tocs) &&
829
629
      tocs != &my_charset_bin)
830
630
  {
831
631
    /* Store with conversion */
832
 
    return net_store_data((unsigned char*) from, length, fromcs, tocs);
 
632
    return netStoreData((unsigned char*) from, length, fromcs, tocs);
833
633
  }
834
634
  /* Store without conversion */
835
 
  return net_store_data((unsigned char*) from, length);
836
 
}
837
 
 
838
 
 
839
 
bool Protocol_text::store(const char *from, size_t length,
840
 
                          const CHARSET_INFO * const fromcs,
841
 
                                                  const CHARSET_INFO * const tocs)
842
 
{
843
 
  return store_string_aux(from, length, fromcs, tocs);
844
 
}
845
 
 
846
 
 
847
 
bool Protocol_text::store(const char *from, size_t length,
 
635
  return netStoreData((unsigned char*) from, length);
 
636
}
 
637
 
 
638
 
 
639
bool ProtocolOldLibdrizzle::store(const char *from, size_t length,
848
640
                          const CHARSET_INFO * const fromcs)
849
641
{
850
642
  const CHARSET_INFO * const tocs= default_charset_info;
851
 
  return store_string_aux(from, length, fromcs, tocs);
852
 
}
853
 
 
854
 
 
855
 
bool Protocol_text::store_tiny(int64_t from)
856
 
{
857
 
  char buff[20];
858
 
  return net_store_data((unsigned char*) buff,
859
 
                        (size_t) (int10_to_str((int) from, buff, -10) - buff));
860
 
}
861
 
 
862
 
 
863
 
bool Protocol_text::store_short(int64_t from)
864
 
{
865
 
  char buff[20];
866
 
  return net_store_data((unsigned char*) buff,
867
 
                        (size_t) (int10_to_str((int) from, buff, -10) -
868
 
                                  buff));
869
 
}
870
 
 
871
 
 
872
 
bool Protocol_text::store_long(int64_t from)
873
 
{
874
 
  char buff[20];
875
 
  return net_store_data((unsigned char*) buff,
876
 
                        (size_t) (int10_to_str((long int)from, buff,
877
 
                                               (from <0)?-10:10)-buff));
878
 
}
879
 
 
880
 
 
881
 
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
 
643
  return storeString(from, length, fromcs, tocs);
 
644
}
 
645
 
 
646
 
 
647
bool ProtocolOldLibdrizzle::store(int32_t from)
 
648
{
 
649
  char buff[12];
 
650
  return netStoreData((unsigned char*) buff,
 
651
                      (size_t) (int10_to_str(from, buff, -10) - buff));
 
652
}
 
653
 
 
654
bool ProtocolOldLibdrizzle::store(uint32_t from)
 
655
{
 
656
  char buff[11];
 
657
  return netStoreData((unsigned char*) buff,
 
658
                      (size_t) (int10_to_str(from, buff, 10) - buff));
 
659
}
 
660
 
 
661
bool ProtocolOldLibdrizzle::store(int64_t from)
882
662
{
883
663
  char buff[22];
884
 
  return net_store_data((unsigned char*) buff,
885
 
                        (size_t) (int64_t10_to_str(from,buff,
886
 
                                                    unsigned_flag ? 10 : -10)-
887
 
                                  buff));
888
 
}
889
 
 
890
 
 
891
 
bool Protocol_text::store_decimal(const my_decimal *d)
892
 
{
893
 
  char buff[DECIMAL_MAX_STR_LENGTH];
894
 
  String str(buff, sizeof(buff), &my_charset_bin);
895
 
  (void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
896
 
  return net_store_data((unsigned char*) str.ptr(), str.length());
897
 
}
898
 
 
899
 
 
900
 
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
901
 
{
902
 
  buffer->set_real((double) from, decimals, session->charset());
903
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
904
 
}
905
 
 
906
 
 
907
 
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
 
664
  return netStoreData((unsigned char*) buff,
 
665
                      (size_t) (int64_t10_to_str(from, buff, -10) - buff));
 
666
}
 
667
 
 
668
bool ProtocolOldLibdrizzle::store(uint64_t from)
 
669
{
 
670
  char buff[21];
 
671
  return netStoreData((unsigned char*) buff,
 
672
                      (size_t) (int64_t10_to_str(from, buff, 10) - buff));
 
673
}
 
674
 
 
675
 
 
676
bool ProtocolOldLibdrizzle::store(double from, uint32_t decimals, String *buffer)
908
677
{
909
678
  buffer->set_real(from, decimals, session->charset());
910
 
  return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
 
679
  return netStoreData((unsigned char*) buffer->ptr(), buffer->length());
911
680
}
912
681
 
913
682
 
914
 
bool Protocol_text::store(Field *field)
 
683
bool ProtocolOldLibdrizzle::store(Field *from)
915
684
{
916
 
  if (field->is_null())
917
 
    return store_null();
 
685
  if (from->is_null())
 
686
    return store();
918
687
  char buff[MAX_FIELD_WIDTH];
919
688
  String str(buff,sizeof(buff), &my_charset_bin);
920
689
  const CHARSET_INFO * const tocs= default_charset_info;
921
690
 
922
 
  field->val_str(&str);
923
 
 
924
 
  return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
925
 
}
926
 
 
927
 
 
928
 
/**
929
 
  @todo
930
 
    Second_part format ("%06") needs to change when
931
 
    we support 0-6 decimals for time.
932
 
*/
933
 
 
934
 
bool Protocol_text::store(DRIZZLE_TIME *tm)
935
 
{
936
 
  char buff[40];
937
 
  uint32_t length;
938
 
  length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
939
 
                           (int) tm->year,
940
 
                           (int) tm->month,
941
 
                           (int) tm->day,
942
 
                           (int) tm->hour,
943
 
                           (int) tm->minute,
944
 
                           (int) tm->second);
945
 
  if (tm->second_part)
946
 
    length+= sprintf(buff+length, ".%06d",
947
 
                                     (int)tm->second_part);
948
 
  return net_store_data((unsigned char*) buff, length);
949
 
}
950
 
 
951
 
 
952
 
bool Protocol_text::store_date(DRIZZLE_TIME *tm)
953
 
{
954
 
  char buff[MAX_DATE_STRING_REP_LENGTH];
955
 
  size_t length= my_date_to_str(tm, buff);
956
 
  return net_store_data((unsigned char*) buff, length);
957
 
}
958
 
 
959
 
 
960
 
/**
961
 
  @todo
962
 
    Second_part format ("%06") needs to change when
963
 
    we support 0-6 decimals for time.
964
 
*/
965
 
 
966
 
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
967
 
{
968
 
  char buff[40];
969
 
  uint32_t length;
970
 
  uint32_t day= (tm->year || tm->month) ? 0 : tm->day;
971
 
  length= sprintf(buff, "%s%02ld:%02d:%02d",
972
 
                           tm->neg ? "-" : "",
973
 
                           (long) day*24L+(long) tm->hour,
974
 
                           (int) tm->minute,
975
 
                           (int) tm->second);
976
 
  if (tm->second_part)
977
 
    length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
978
 
  return net_store_data((unsigned char*) buff, length);
979
 
}
980
 
 
981
 
bool Protocol_text::_check_connection(void)
 
691
  from->val_str(&str);
 
692
 
 
693
  return storeString(str.ptr(), str.length(), str.charset(), tocs);
 
694
}
 
695
 
 
696
 
 
697
/**
 
698
  @todo
 
699
    Second_part format ("%06") needs to change when
 
700
    we support 0-6 decimals for time.
 
701
*/
 
702
 
 
703
bool ProtocolOldLibdrizzle::store(const DRIZZLE_TIME *tm)
 
704
{
 
705
  char buff[40];
 
706
  uint32_t length;
 
707
  uint32_t day;
 
708
 
 
709
  switch (tm->time_type)
 
710
  {
 
711
  case DRIZZLE_TIMESTAMP_DATETIME:
 
712
    length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
 
713
                    (int) tm->year,
 
714
                    (int) tm->month,
 
715
                    (int) tm->day,
 
716
                    (int) tm->hour,
 
717
                    (int) tm->minute,
 
718
                    (int) tm->second);
 
719
    if (tm->second_part)
 
720
      length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
 
721
    break;
 
722
 
 
723
  case DRIZZLE_TIMESTAMP_DATE:
 
724
    length= sprintf(buff, "%04d-%02d-%02d",
 
725
                    (int) tm->year,
 
726
                    (int) tm->month,
 
727
                    (int) tm->day);
 
728
    break;
 
729
 
 
730
  case DRIZZLE_TIMESTAMP_TIME:
 
731
    day= (tm->year || tm->month) ? 0 : tm->day;
 
732
    length= sprintf(buff, "%s%02ld:%02d:%02d", tm->neg ? "-" : "",
 
733
                    (long) day*24L+(long) tm->hour, (int) tm->minute,
 
734
                    (int) tm->second);
 
735
    if (tm->second_part)
 
736
      length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
 
737
    break;
 
738
 
 
739
  case DRIZZLE_TIMESTAMP_NONE:
 
740
  case DRIZZLE_TIMESTAMP_ERROR:
 
741
  default:
 
742
    assert(0);
 
743
    return false;
 
744
  }
 
745
 
 
746
  return netStoreData((unsigned char*) buff, length);
 
747
}
 
748
 
 
749
bool ProtocolOldLibdrizzle::checkConnection(void)
982
750
{
983
751
  uint32_t pkt_len= 0;
984
752
  char *end;
1022
790
      procedure, scramble is set here. This gives us new scramble for
1023
791
      each handshake.
1024
792
    */
1025
 
    drizzleclient_create_random_string(_scramble, SCRAMBLE_LENGTH, &_rand);
 
793
    drizzleclient_create_random_string(scramble, SCRAMBLE_LENGTH, &rand);
1026
794
    /*
1027
795
      Old clients does not understand long scrambles, but can ignore packet
1028
796
      tail: that's why first part of the scramble is placed here, and second
1029
797
      part at the end of packet.
1030
798
    */
1031
 
    end= strncpy(end, _scramble, SCRAMBLE_LENGTH_323);
 
799
    end= strncpy(end, scramble, SCRAMBLE_LENGTH_323);
1032
800
    end+= SCRAMBLE_LENGTH_323;
1033
801
 
1034
802
    *end++= 0; /* an empty byte for some reason */
1041
809
    end+= 18;
1042
810
    /* write scramble tail */
1043
811
    size_t scramble_len= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323;
1044
 
    end= strncpy(end, _scramble + SCRAMBLE_LENGTH_323, scramble_len);
 
812
    end= strncpy(end, scramble + SCRAMBLE_LENGTH_323, scramble_len);
1045
813
    end+= scramble_len;
1046
814
 
1047
815
    *end++= 0; /* an empty byte for some reason */
1053
821
          , 0
1054
822
          , (unsigned char*) buff
1055
823
          , (size_t) (end-buff)) 
1056
 
        ||      (pkt_len= drizzleclient_net_read(&net)) == packet_error 
 
824
        ||    (pkt_len= drizzleclient_net_read(&net)) == packet_error 
1057
825
        || pkt_len < MIN_HANDSHAKE_SIZE)
1058
826
    {
1059
827
      my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1090
858
  uint32_t user_len= passwd - user - 1;
1091
859
  char *l_db= passwd;
1092
860
  char db_buff[NAME_LEN + 1];           // buffer to store db in utf8
1093
 
  char user_buff[USERNAME_LENGTH + 1];  // buffer to store user in utf8
 
861
  char user_buff[USERNAME_LENGTH + 1];    // buffer to store user in utf8
1094
862
  uint32_t dummy_errors;
1095
863
 
1096
864
  /*
1143
911
 
1144
912
  return session->checkUser(passwd, passwd_len, l_db);
1145
913
}
 
914
 
 
915
static int init(void *p)
 
916
{
 
917
  ProtocolFactory **factory= static_cast<ProtocolFactory **>(p);
 
918
  *factory= new ProtocolFactoryOldLibdrizzle;
 
919
  return 0;
 
920
}
 
921
 
 
922
static int deinit(void *p)
 
923
{
 
924
  ProtocolFactoryOldLibdrizzle *factory= static_cast<ProtocolFactoryOldLibdrizzle *>(p);
 
925
  delete factory;
 
926
  return 0;
 
927
}
 
928
 
 
929
drizzle_declare_plugin(oldlibdrizzle)
 
930
{
 
931
  DRIZZLE_PROTOCOL_PLUGIN,
 
932
  "oldlibdrizzle",
 
933
  "0.1",
 
934
  "Eric Day",
 
935
  "Old libdrizzle Protocol",
 
936
  PLUGIN_LICENSE_GPL,
 
937
  init,   /* Plugin Init */
 
938
  deinit, /* Plugin Deinit */
 
939
  NULL,   /* status variables */
 
940
  NULL,   /* system variables */
 
941
  NULL    /* config options */
 
942
}
 
943
drizzle_declare_plugin_end;