1
/* Copyright (C) 2000-2003 MySQL AB
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.
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.
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:
4
* Copyright (C) 2008 Sun Microsystems
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.
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.
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
53
58
static void write_eof_packet(Session *session, NET *net,
54
59
uint32_t server_status, uint32_t total_warn_count);
56
bool Protocol::io_ok()
61
bool Protocol_libdrizzleclient::isConnected()
58
63
return net.vio != 0;
61
void Protocol::set_read_timeout(uint32_t timeout)
66
void Protocol_libdrizzleclient::set_read_timeout(uint32_t timeout)
63
68
drizzleclient_net_set_read_timeout(&net, timeout);
66
void Protocol::set_write_timeout(uint32_t timeout)
71
void Protocol_libdrizzleclient::set_write_timeout(uint32_t timeout)
68
73
drizzleclient_net_set_write_timeout(&net, timeout);
71
void Protocol::set_retry_count(uint32_t count)
76
void Protocol_libdrizzleclient::set_retry_count(uint32_t count)
73
78
net.retry_count=count;
76
void Protocol::set_error(char error)
81
void Protocol_libdrizzleclient::set_error(char error)
81
bool Protocol::have_error(void)
86
bool Protocol_libdrizzleclient::have_error(void)
83
88
return net.error || net.vio == 0;
86
bool Protocol::was_aborted(void)
91
bool Protocol_libdrizzleclient::was_aborted(void)
88
93
return net.error && net.vio != 0;
91
bool Protocol::have_more_data(void)
96
bool Protocol_libdrizzleclient::have_more_data(void)
93
98
return drizzleclient_net_more_data(&net);
96
bool Protocol::have_compression(void)
101
bool Protocol_libdrizzleclient::have_compression(void)
98
103
return net.compress;
101
void Protocol::enable_compression(void)
106
void Protocol_libdrizzleclient::enable_compression(void)
103
108
net.compress= true;
106
bool Protocol::is_reading(void)
111
bool Protocol_libdrizzleclient::is_reading(void)
108
113
return net.reading_or_writing == 1;
111
bool Protocol::is_writing(void)
116
bool Protocol_libdrizzleclient::is_writing(void)
113
118
return net.reading_or_writing == 2;
117
* To disable results we set net.vio to 0.
120
void Protocol::disable_results(void)
126
void Protocol::enable_results(void)
132
bool Protocol::net_store_data(const unsigned char *from, size_t length)
121
bool Protocol_libdrizzleclient::netStoreData(const unsigned char *from, size_t length)
134
123
size_t packet_length= packet->length();
263
251
session->main_da.can_overwrite_status= false;
254
void Protocol_libdrizzleclient::sendOK()
256
unsigned char buff[DRIZZLE_ERRMSG_SIZE+10],*pos;
257
const char *message= NULL;
260
if (!net.vio) // hack for re-parsing queries
265
buff[0]=0; // No fields
266
if (session->main_da.status() == Diagnostics_area::DA_OK)
268
pos=drizzleclient_net_store_length(buff+1,session->main_da.affected_rows());
269
pos=drizzleclient_net_store_length(pos, session->main_da.last_insert_id());
270
int2store(pos, session->main_da.server_status());
272
tmp= cmin(session->main_da.total_warn_count(), (uint32_t)65535);
273
message= session->main_da.message();
277
pos=drizzleclient_net_store_length(buff+1,0);
278
pos=drizzleclient_net_store_length(pos, 0);
279
int2store(pos, session->server_status);
281
tmp= cmin(session->total_warn_count, (uint32_t)65535);
284
/* We can only return up to 65535 warnings in two bytes */
288
session->main_da.can_overwrite_status= true;
290
if (message && message[0])
292
size_t length= strlen(message);
293
pos=drizzleclient_net_store_length(pos,length);
294
memcpy(pos,(unsigned char*) message,length);
297
drizzleclient_net_write(&net, buff, (size_t) (pos-buff));
298
drizzleclient_net_flush(&net);
300
session->main_da.can_overwrite_status= false;
267
304
Send eof (= end of result set) to the client.
381
431
/* Abort multi-result sets */
382
432
session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
384
send_error_packet(sql_errno, err);
434
sendErrorPacket(sql_errno, err);
386
436
session->main_da.can_overwrite_status= false;
391
Send the status of the current statement execution over network.
393
@param session in fact, carries two parameters, NET for the transport and
394
Diagnostics_area as the source of status information.
396
In MySQL, there are two types of SQL statements: those that return
397
a result set and those that return status information only.
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
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.
418
A statement that does not return a result set doesn't send result
419
set meta-data either. Instead it returns one of:
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.
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.
430
@post The status information is encoded to protocol format and sent to the
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
437
Diagnostics_area::is_sent is set for debugging purposes only.
440
void Protocol::end_statement()
442
assert(! session->main_da.is_sent);
444
/* Can not be true, but do not take chances in production. */
445
if (session->main_da.is_sent)
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());
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());
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());
467
case Diagnostics_area::DA_DISABLED:
469
case Diagnostics_area::DA_EMPTY:
471
//TODO: Something is being masked here by commenting this out
473
net_send_ok(session, &net, session->server_status, session->total_warn_count,
477
session->main_da.is_sent= true;
481
439
/*****************************************************************************
482
440
Default Protocol functions
483
441
*****************************************************************************/
485
void Protocol::init(Session *session_arg)
443
Protocol_libdrizzleclient::Protocol_libdrizzleclient()
449
void Protocol_libdrizzleclient::setSession(Session *session_arg)
451
session= session_arg;
488
452
packet= &session->packet;
489
453
convert= &session->convert_buffer;
494
bool Protocol::flush()
456
bool Protocol_libdrizzleclient::flush()
496
458
return drizzleclient_net_flush(&net);
686
648
All data are sent as 'packed-string-length' followed by 'string-data'
687
649
****************************************************************************/
689
void Protocol_text::init_random(uint64_t seed1, uint64_t seed2)
651
void Protocol_libdrizzleclient::init_random(uint64_t seed1, uint64_t seed2)
691
drizzleclient_randominit(&_rand, seed1, seed2);
653
drizzleclient_randominit(&rand, seed1, seed2);
694
bool Protocol_text::init_file_descriptor(int fd)
656
bool Protocol_libdrizzleclient::init_file_descriptor(int fd)
696
658
if (drizzleclient_net_init_sock(&net, fd, 0))
701
int Protocol_text::file_descriptor(void)
663
int Protocol_libdrizzleclient::file_descriptor(void)
703
665
return drizzleclient_net_get_sd(&net);
706
bool Protocol_text::authenticate()
668
bool Protocol_libdrizzleclient::authenticate()
708
670
bool connection_is_valid;
829
788
tocs != &my_charset_bin)
831
790
/* Store with conversion */
832
return net_store_data((unsigned char*) from, length, fromcs, tocs);
791
return netStoreData((unsigned char*) from, length, fromcs, tocs);
834
793
/* Store without conversion */
835
return net_store_data((unsigned char*) from, length);
794
return netStoreData((unsigned char*) from, length);
839
bool Protocol_text::store(const char *from, size_t length,
798
bool Protocol_libdrizzleclient::store(const char *from, size_t length,
840
799
const CHARSET_INFO * const fromcs,
841
800
const CHARSET_INFO * const tocs)
843
return store_string_aux(from, length, fromcs, tocs);
802
return storeStringAux(from, length, fromcs, tocs);
847
bool Protocol_text::store(const char *from, size_t length,
806
bool Protocol_libdrizzleclient::store(const char *from, size_t length,
848
807
const CHARSET_INFO * const fromcs)
850
809
const CHARSET_INFO * const tocs= default_charset_info;
851
return store_string_aux(from, length, fromcs, tocs);
810
return storeStringAux(from, length, fromcs, tocs);
855
bool Protocol_text::store_tiny(int64_t from)
814
bool Protocol_libdrizzleclient::store_tiny(int64_t from)
858
return net_store_data((unsigned char*) buff,
817
return netStoreData((unsigned char*) buff,
859
818
(size_t) (int10_to_str((int) from, buff, -10) - buff));
863
bool Protocol_text::store_short(int64_t from)
822
bool Protocol_libdrizzleclient::store_short(int64_t from)
866
return net_store_data((unsigned char*) buff,
825
return netStoreData((unsigned char*) buff,
867
826
(size_t) (int10_to_str((int) from, buff, -10) -
872
bool Protocol_text::store_long(int64_t from)
831
bool Protocol_libdrizzleclient::store_long(int64_t from)
875
return net_store_data((unsigned char*) buff,
834
return netStoreData((unsigned char*) buff,
876
835
(size_t) (int10_to_str((long int)from, buff,
877
836
(from <0)?-10:10)-buff));
881
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
840
bool Protocol_libdrizzleclient::store_int64_t(int64_t from, bool unsigned_flag)
884
return net_store_data((unsigned char*) buff,
843
return netStoreData((unsigned char*) buff,
885
844
(size_t) (int64_t10_to_str(from,buff,
886
845
unsigned_flag ? 10 : -10)-
891
bool Protocol_text::store_decimal(const my_decimal *d)
850
bool Protocol_libdrizzleclient::store_decimal(const my_decimal *d)
893
852
char buff[DECIMAL_MAX_STR_LENGTH];
894
853
String str(buff, sizeof(buff), &my_charset_bin);
895
854
(void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
896
return net_store_data((unsigned char*) str.ptr(), str.length());
855
return netStoreData((unsigned char*) str.ptr(), str.length());
900
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
859
bool Protocol_libdrizzleclient::store(float from, uint32_t decimals, String *buffer)
902
861
buffer->set_real((double) from, decimals, session->charset());
903
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
862
return netStoreData((unsigned char*) buffer->ptr(), buffer->length());
907
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
866
bool Protocol_libdrizzleclient::store(double from, uint32_t decimals, String *buffer)
909
868
buffer->set_real(from, decimals, session->charset());
910
return net_store_data((unsigned char*) buffer->ptr(), buffer->length());
869
return netStoreData((unsigned char*) buffer->ptr(), buffer->length());
914
bool Protocol_text::store(Field *field)
873
bool Protocol_libdrizzleclient::store(Field *field)
916
875
if (field->is_null())
917
876
return store_null();
1022
981
procedure, scramble is set here. This gives us new scramble for
1025
drizzleclient_create_random_string(_scramble, SCRAMBLE_LENGTH, &_rand);
984
drizzleclient_create_random_string(scramble, SCRAMBLE_LENGTH, &rand);
1027
986
Old clients does not understand long scrambles, but can ignore packet
1028
987
tail: that's why first part of the scramble is placed here, and second
1029
988
part at the end of packet.
1031
end= strncpy(end, _scramble, SCRAMBLE_LENGTH_323);
990
end= strncpy(end, scramble, SCRAMBLE_LENGTH_323);
1032
991
end+= SCRAMBLE_LENGTH_323;
1034
993
*end++= 0; /* an empty byte for some reason */