1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2010 Brian Aker
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; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
#include <drizzled/gettext.h>
24
#include <drizzled/error.h>
25
#include <drizzled/query_id.h>
26
#include <drizzled/session.h>
27
#include <drizzled/internal/my_sys.h>
28
#include <drizzled/internal/m_string.h>
31
#include <boost/program_options.hpp>
32
#include <drizzled/module/option_map.h>
33
#include <drizzled/util/tokenize.h>
34
#include "drizzle_protocol.h"
36
namespace po= boost::program_options;
37
using namespace drizzled;
40
namespace drizzle_plugin
42
namespace drizzle_protocol
45
std::vector<std::string> ClientDrizzleProtocol::drizzle_admin_ip_addresses;
46
static port_constraint port;
47
static timeout_constraint connect_timeout;
48
static timeout_constraint read_timeout;
49
static timeout_constraint write_timeout;
50
static retry_constraint retry_count;
51
static buffer_constraint buffer_length;
53
static const uint32_t DRIZZLE_TCP_PORT= 4427;
55
ProtocolCounters *ListenDrizzleProtocol::drizzle_counters= new ProtocolCounters();
57
ListenDrizzleProtocol::~ListenDrizzleProtocol()
61
in_port_t ListenDrizzleProtocol::getPort(void) const
66
void ClientDrizzleProtocol::drizzle_compose_ip_addresses(vector<string> options)
68
for (vector<string>::iterator it= options.begin();
72
tokenize(*it, drizzle_admin_ip_addresses, ",", true);
76
bool ClientDrizzleProtocol::isAdminAllowed(void)
78
if (std::find(drizzle_admin_ip_addresses.begin(), drizzle_admin_ip_addresses.end(), session->user()->address()) != drizzle_admin_ip_addresses.end())
84
plugin::Client *ListenDrizzleProtocol::getClient(int fd)
87
new_fd= acceptTcp(fd);
91
return new ClientDrizzleProtocol(new_fd, getCounters());
94
static int init(drizzled::module::Context &context)
96
const module::option_map &vm= context.getOptions();
98
ListenDrizzleProtocol *protocol=new ListenDrizzleProtocol("drizzle_protocol", vm["bind-address"].as<std::string>(), true);
99
protocol->addCountersToTable();
100
context.add(protocol);
101
context.registerVariable(new sys_var_constrained_value_readonly<in_port_t>("port", port));
102
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("connect_timeout", connect_timeout));
103
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("read_timeout", read_timeout));
104
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("write_timeout", write_timeout));
105
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("retry_count", retry_count));
106
context.registerVariable(new sys_var_constrained_value_readonly<uint32_t>("buffer_length", buffer_length));
107
context.registerVariable(new sys_var_const_string_val("bind_address",
108
vm["bind-address"].as<std::string>()));
110
context.registerVariable(new sys_var_uint32_t_ptr("max-connections", &ListenDrizzleProtocol::drizzle_counters->max_connections));
116
static void init_options(drizzled::module::option_context &context)
119
po::value<port_constraint>(&port)->default_value(DRIZZLE_TCP_PORT),
120
N_("Port number to use for connection or 0 for default to with Drizzle/MySQL protocol."));
121
context("connect-timeout",
122
po::value<timeout_constraint>(&connect_timeout)->default_value(10),
123
N_("Connect Timeout."));
124
context("read-timeout",
125
po::value<timeout_constraint>(&read_timeout)->default_value(30),
126
N_("Read Timeout."));
127
context("write-timeout",
128
po::value<timeout_constraint>(&write_timeout)->default_value(60),
129
N_("Write Timeout."));
130
context("retry-count",
131
po::value<retry_constraint>(&retry_count)->default_value(10),
133
context("buffer-length",
134
po::value<buffer_constraint>(&buffer_length)->default_value(16384),
135
N_("Buffer length."));
136
context("bind-address",
137
po::value<std::string>()->default_value(""),
138
N_("Address to bind to."));
139
context("max-connections",
140
po::value<uint32_t>(&ListenDrizzleProtocol::drizzle_counters->max_connections)->default_value(1000),
141
N_("Maximum simultaneous connections."));
142
context("admin-ip-addresses",
143
po::value<vector<string> >()->composing()->notifier(&ClientDrizzleProtocol::drizzle_compose_ip_addresses),
144
N_("A restrictive IP address list for incoming admin connections."));
147
} /* namespace drizzle_protocol */
148
} /* namespace drizzle_plugin */
150
DRIZZLE_PLUGIN(drizzle_plugin::drizzle_protocol::init, NULL, drizzle_plugin::drizzle_protocol::init_options);
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 */
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
23
#ifdef USE_PRAGMA_IMPLEMENTATION
24
#pragma implementation // gcc: Class implementation
27
#include "mysql_priv.h"
29
#include <drizzled/drizzled_error_messages.h>
31
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
32
/* Declared non-static only because of the embedded library. */
33
static void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
34
static void write_eof_packet(THD *thd, NET *net,
35
uint server_status, uint total_warn_count);
37
bool Protocol::net_store_data(const uchar *from, size_t length)
39
ulong packet_length=packet->length();
41
The +9 comes from that strings of length longer than 16M require
42
9 bytes to be stored (see net_store_length).
44
if (packet_length+9+length > packet->alloced_length() &&
45
packet->realloc(packet_length+9+length))
47
uchar *to= net_store_length((uchar*) packet->ptr()+packet_length, length);
48
memcpy(to,from,length);
49
packet->length((uint) (to+length-(uchar*) packet->ptr()));
57
net_store_data() - extended version with character set conversion.
59
It is optimized for short strings whose length after
60
conversion is garanteed to be less than 251, which accupies
61
exactly one byte to store length. It allows not to use
62
the "convert" member as a temporary buffer, conversion
63
is done directly to the "packet" member.
64
The limit 251 is good enough to optimize send_fields()
65
because column, table, database names fit into this limit.
68
bool Protocol::net_store_data(const uchar *from, size_t length,
69
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
72
/* Calculate maxumum possible result length */
73
uint conv_length= to_cs->mbmaxlen * length / from_cs->mbminlen;
74
if (conv_length > 250)
77
For strings with conv_length greater than 250 bytes
78
we don't know how many bytes we will need to store length: one or two,
79
because we don't know result length until conversion is done.
80
For example, when converting from utf8 (mbmaxlen=3) to latin1,
81
conv_length=300 means that the result length can vary between 100 to 300.
82
length=100 needs one byte, length=300 needs to bytes.
84
Thus conversion directly to "packet" is not worthy.
85
Let's use "convert" as a temporary buffer.
87
return (convert->copy((const char*) from, length, from_cs,
88
to_cs, &dummy_errors) ||
89
net_store_data((const uchar*) convert->ptr(), convert->length()));
92
ulong packet_length= packet->length();
93
ulong new_length= packet_length + conv_length + 1;
95
if (new_length > packet->alloced_length() && packet->realloc(new_length))
98
char *length_pos= (char*) packet->ptr() + packet_length;
99
char *to= length_pos + 1;
101
to+= copy_and_convert(to, conv_length, to_cs,
102
(const char*) from, length, from_cs, &dummy_errors);
104
net_store_length((uchar*) length_pos, to - length_pos - 1);
105
packet->length((uint) (to - packet->ptr()));
111
Send a error string to client.
114
net_printf_error and net_send_error are low-level functions
115
that shall be used only when a new connection is being
116
established or at server startup.
118
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
119
critical that every error that can be intercepted is issued in one
120
place only, my_message_sql.
122
void net_send_error(THD *thd, uint sql_errno, const char *err)
125
assert(err && err[0]);
128
It's one case when we can push an error even though there
129
is an OK or EOF already.
131
thd->main_da.can_overwrite_status= true;
133
/* Abort multi-result sets */
134
thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
136
net_send_error_packet(thd, sql_errno, err);
138
thd->main_da.can_overwrite_status= false;
144
Return ok to the client.
146
The ok packet has the following structure:
148
- 0 : Marker (1 byte)
149
- affected_rows : Stored in 1-9 bytes
150
- id : Stored in 1-9 bytes
151
- server_status : Copy of thd->server_status; Can be used by client
152
to check if we are inside an transaction.
154
- warning_count : Stored in 2 bytes; New in 4.1 protocol
155
- message : Stored as packed length (1-9 bytes) + message.
156
Is not stored if no message.
158
@param thd Thread handler
159
@param affected_rows Number of rows changed by statement
160
@param id Auto_increment id for first row (if used)
161
@param message Message to send to the client (Used by mysql_status)
165
net_send_ok(THD *thd,
166
uint server_status, uint total_warn_count,
167
ha_rows affected_rows, uint64_t id, const char *message)
170
uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
172
if (! net->vio) // hack for re-parsing queries
177
buff[0]=0; // No fields
178
pos=net_store_length(buff+1,affected_rows);
179
pos=net_store_length(pos, id);
180
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
182
int2store(pos, server_status);
185
/* We can only return up to 65535 warnings in two bytes */
186
uint tmp= min(total_warn_count, 65535);
190
else if (net->return_status) // For 4.0 protocol
192
int2store(pos, server_status);
195
thd->main_da.can_overwrite_status= true;
197
if (message && message[0])
198
pos= net_store_data(pos, (uchar*) message, strlen(message));
199
VOID(my_net_write(net, buff, (size_t) (pos-buff)));
200
VOID(net_flush(net));
202
thd->main_da.can_overwrite_status= false;
207
static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
210
Send eof (= end of result set) to the client.
212
The eof packet has the following structure:
214
- 254 : Marker (1 byte)
215
- warning_count : Stored in 2 bytes; New in 4.1 protocol
216
- status_flag : Stored in 2 bytes;
217
For flags like SERVER_MORE_RESULTS_EXISTS.
219
Note that the warning count will not be sent if 'no_flush' is set as
220
we don't want to report the warning count until all data is sent to the
223
@param thd Thread handler
224
@param no_flush Set to 1 if there will be more data to the client,
225
like in send_fields().
229
net_send_eof(THD *thd, uint server_status, uint total_warn_count)
232
/* Set to true if no active vio, to work well in case of --init-file */
235
thd->main_da.can_overwrite_status= true;
236
write_eof_packet(thd, net, server_status, total_warn_count);
237
VOID(net_flush(net));
238
thd->main_da.can_overwrite_status= false;
245
Format EOF packet according to the current protocol and
246
write it to the network output buffer.
249
static void write_eof_packet(THD *thd, NET *net,
251
uint total_warn_count)
253
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
257
Don't send warn count during SP execution, as the warn_list
258
is cleared between substatements, and mysqltest gets confused
260
uint tmp= min(total_warn_count, 65535);
262
int2store(buff+1, tmp);
264
The following test should never be true, but it's better to do it
265
because if 'is_fatal_error' is set the server is not going to execute
266
other queries (see the if test in dispatch_command / COM_QUERY)
268
if (thd->is_fatal_error)
269
server_status&= ~SERVER_MORE_RESULTS_EXISTS;
270
int2store(buff + 3, server_status);
271
VOID(my_net_write(net, buff, 5));
274
VOID(my_net_write(net, eof_buff, 1));
277
void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
282
buff[]: sql_errno:2 + ('#':1 + SQLSTATE_LENGTH:5) + MYSQL_ERRMSG_SIZE:512
284
uchar buff[2+1+SQLSTATE_LENGTH+MYSQL_ERRMSG_SIZE], *pos;
291
int2store(buff,sql_errno);
293
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
295
/* The first # is to make the protocol backward compatible */
297
pos= (uchar*) strmov((char*) buff+3, mysql_errno_to_sqlstate(sql_errno));
299
length= (uint) (strmake((char*) pos, err, MYSQL_ERRMSG_SIZE-1) -
303
VOID(net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) err,
310
Faster net_store_length when we know that length is less than 65536.
311
We keep a separate version for that range because it's widely used in
314
uint is used as agrument type because of MySQL type conventions:
316
- ulong for 0..4294967296
317
- uint64_t for bigger numbers.
320
static uchar *net_store_length_fast(uchar *packet, uint length)
324
*packet=(uchar) length;
328
int2store(packet,(uint) length);
333
Send the status of the current statement execution over network.
335
@param thd in fact, carries two parameters, NET for the transport and
336
Diagnostics_area as the source of status information.
338
In MySQL, there are two types of SQL statements: those that return
339
a result set and those that return status information only.
341
If a statement returns a result set, it consists of 3 parts:
342
- result set meta-data
343
- variable number of result set rows (can be 0)
344
- followed and terminated by EOF or ERROR packet
346
Once the client has seen the meta-data information, it always
347
expects an EOF or ERROR to terminate the result set. If ERROR is
348
received, the result set rows are normally discarded (this is up
349
to the client implementation, libmysql at least does discard them).
350
EOF, on the contrary, means "successfully evaluated the entire
351
result set". Since we don't know how many rows belong to a result
352
set until it's evaluated, EOF/ERROR is the indicator of the end
353
of the row stream. Note, that we can not buffer result set rows
354
on the server -- there may be an arbitrary number of rows. But
355
we do buffer the last packet (EOF/ERROR) in the Diagnostics_area and
356
delay sending it till the very end of execution (here), to be able to
357
change EOF to an ERROR if commit failed or some other error occurred
358
during the last cleanup steps taken after execution.
360
A statement that does not return a result set doesn't send result
361
set meta-data either. Instead it returns one of:
364
Similarly to the EOF/ERROR of the previous statement type, OK/ERROR
365
packet is "buffered" in the diagnostics area and sent to the client
366
in the end of statement.
368
@pre The diagnostics area is assigned or disabled. It can not be empty
369
-- we assume that every SQL statement or COM_* command
370
generates OK, ERROR, or EOF status.
372
@post The status information is encoded to protocol format and sent to the
375
@return We conventionally return void, since the only type of error
376
that can happen here is a NET (transport) error, and that one
377
will become visible when we attempt to read from the NET the
379
Diagnostics_area::is_sent is set for debugging purposes only.
382
void net_end_statement(THD *thd)
384
assert(! thd->main_da.is_sent);
386
/* Can not be true, but do not take chances in production. */
387
if (thd->main_da.is_sent)
390
switch (thd->main_da.status()) {
391
case Diagnostics_area::DA_ERROR:
392
/* The query failed, send error to log and abort bootstrap. */
394
thd->main_da.sql_errno(),
395
thd->main_da.message());
397
case Diagnostics_area::DA_EOF:
399
thd->main_da.server_status(),
400
thd->main_da.total_warn_count());
402
case Diagnostics_area::DA_OK:
404
thd->main_da.server_status(),
405
thd->main_da.total_warn_count(),
406
thd->main_da.affected_rows(),
407
thd->main_da.last_insert_id(),
408
thd->main_da.message());
410
case Diagnostics_area::DA_DISABLED:
412
case Diagnostics_area::DA_EMPTY:
415
net_send_ok(thd, thd->server_status, thd->total_warn_count,
419
thd->main_da.is_sent= true;
423
/****************************************************************************
424
Functions used by the protocol functions (like net_send_ok) to store
425
strings and numbers in the header result packet.
426
****************************************************************************/
428
/* The following will only be used for short strings < 65K */
430
uchar *net_store_data(uchar *to, const uchar *from, size_t length)
432
to=net_store_length_fast(to,length);
433
memcpy(to,from,length);
437
uchar *net_store_data(uchar *to,int32_t from)
440
uint length=(uint) (int10_to_str(from,buff,10)-buff);
441
to=net_store_length_fast(to,length);
442
memcpy(to,buff,length);
446
uchar *net_store_data(uchar *to,int64_t from)
449
uint length=(uint) (int64_t10_to_str(from,buff,10)-buff);
450
to=net_store_length_fast(to,length);
451
memcpy(to,buff,length);
456
/*****************************************************************************
457
Default Protocol functions
458
*****************************************************************************/
460
void Protocol::init(THD *thd_arg)
463
packet= &thd->packet;
464
convert= &thd->convert_buffer;
468
Finish the result set with EOF packet, as is expected by the client,
469
if there is an error evaluating the next row and a continue handler
473
void Protocol::end_partial_result_set(THD *thd)
475
net_send_eof(thd, thd->server_status, 0 /* no warnings, we're inside SP */);
479
bool Protocol::flush()
481
return net_flush(&thd->net);
486
Send name and type of result to client.
488
Sum fields has table name empty and field_name.
490
@param THD Thread data object
491
@param list List of items to send to client
492
@param flag Bit mask with the following functions:
493
- 1 send number of rows
494
- 2 send default values
495
- 4 don't write eof packet
500
1 Error (Note that in this case the error is not sent to the
503
bool Protocol::send_fields(List<Item> *list, uint flags)
505
List_iterator_fast<Item> it(*list);
508
String tmp((char*) buff,sizeof(buff),&my_charset_bin);
509
Protocol_text prot(thd);
510
String *local_packet= prot.storage_packet();
511
CHARSET_INFO *thd_charset= thd->variables.character_set_results;
513
if (flags & SEND_NUM_ROWS)
514
{ // Packet with number of elements
515
uchar *pos= net_store_length(buff, list->elements);
516
(void) my_net_write(&thd->net, buff, (size_t) (pos-buff));
522
CHARSET_INFO *cs= system_charset_info;
524
item->make_field(&field);
526
prot.prepare_for_resend();
528
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
530
if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
531
prot.store(field.db_name, (uint) strlen(field.db_name),
533
prot.store(field.table_name, (uint) strlen(field.table_name),
535
prot.store(field.org_table_name, (uint) strlen(field.org_table_name),
537
prot.store(field.col_name, (uint) strlen(field.col_name),
539
prot.store(field.org_col_name, (uint) strlen(field.org_col_name),
541
local_packet->realloc(local_packet->length()+12))
543
/* Store fixed length fields */
544
pos= (char*) local_packet->ptr()+local_packet->length();
545
*pos++= 12; // Length of packed fields
546
if (item->collation.collation == &my_charset_bin || thd_charset == NULL)
549
int2store(pos, field.charsetnr);
550
int4store(pos+2, field.length);
554
/* With conversion */
556
int2store(pos, thd_charset->number);
558
For TEXT/BLOB columns, field_length describes the maximum data
559
length in bytes. There is no limit to the number of characters
560
that a TEXT column can store, as long as the data fits into
561
the designated space.
562
For the rest of textual columns, field_length is evaluated as
563
char_count * mbmaxlen, where character count is taken from the
564
definition of the column. In other words, the maximum number
565
of characters here is limited by the column definition.
567
max_char_len= field.length / item->collation.collation->mbmaxlen;
568
int4store(pos+2, max_char_len * thd_charset->mbmaxlen);
571
int2store(pos+7,field.flags);
572
pos[9]= (char) field.decimals;
573
pos[10]= 0; // For the future
574
pos[11]= 0; // For the future
579
if (prot.store(field.table_name, (uint) strlen(field.table_name),
581
prot.store(field.col_name, (uint) strlen(field.col_name),
583
local_packet->realloc(local_packet->length()+10))
585
pos= (char*) local_packet->ptr()+local_packet->length();
588
int3store(pos+1,field.length);
592
int2store(pos+7,field.flags);
593
pos[9]= (char) field.decimals;
596
local_packet->length((uint) (pos - local_packet->ptr()));
597
if (flags & SEND_DEFAULTS)
598
item->send(&prot, &tmp); // Send default value
600
break; /* purecov: inspected */
603
if (flags & SEND_EOF)
606
Mark the end of meta-data result set, and store thd->server_status,
607
to show that there is no cursor.
608
Send no warning information, as it will be sent at statement end.
610
write_eof_packet(thd, &thd->net, thd->server_status, thd->total_warn_count);
612
return(prepare_for_send(list));
615
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES),
616
MYF(0)); /* purecov: inspected */
617
return(1); /* purecov: inspected */
621
bool Protocol::write()
623
return(my_net_write(&thd->net, (uchar*) packet->ptr(),
629
Send \\0 end terminated string.
631
@param from NullS or \\0 terminated string
634
In most cases one should use store(from, length) instead of this function
642
bool Protocol::store(const char *from, CHARSET_INFO *cs)
646
uint length= strlen(from);
647
return store(from, length, cs);
652
Send a set of strings as one long string with ',' in between.
655
bool Protocol::store(I_List<i_string>* str_list)
658
String tmp(buf, sizeof(buf), &my_charset_bin);
660
I_List_iterator<i_string> it(*str_list);
669
if ((len= tmp.length()))
670
len--; // Remove last ','
671
return store((char*) tmp.ptr(), len, tmp.charset());
675
/****************************************************************************
676
Functions to handle the simple (default) protocol where everything is
677
This protocol is the one that is used by default between the MySQL server
678
and client when you are not using prepared statements.
680
All data are sent as 'packed-string-length' followed by 'string-data'
681
****************************************************************************/
683
void Protocol_text::prepare_for_resend()
688
bool Protocol_text::store_null()
692
return packet->append(buff, sizeof(buff), PACKET_BUFFER_EXTRA_ALLOC);
697
Auxilary function to convert string to the given character set
698
and store in network buffer.
701
bool Protocol::store_string_aux(const char *from, size_t length,
702
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
704
/* 'tocs' is set 0 when client issues SET character_set_results=NULL */
705
if (tocs && !my_charset_same(fromcs, tocs) &&
706
fromcs != &my_charset_bin &&
707
tocs != &my_charset_bin)
709
/* Store with conversion */
710
return net_store_data((uchar*) from, length, fromcs, tocs);
712
/* Store without conversion */
713
return net_store_data((uchar*) from, length);
717
bool Protocol_text::store(const char *from, size_t length,
718
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
720
return store_string_aux(from, length, fromcs, tocs);
724
bool Protocol_text::store(const char *from, size_t length,
725
CHARSET_INFO *fromcs)
727
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
728
return store_string_aux(from, length, fromcs, tocs);
732
bool Protocol_text::store_tiny(int64_t from)
735
return net_store_data((uchar*) buff,
736
(size_t) (int10_to_str((int) from, buff, -10) - buff));
740
bool Protocol_text::store_short(int64_t from)
743
return net_store_data((uchar*) buff,
744
(size_t) (int10_to_str((int) from, buff, -10) -
749
bool Protocol_text::store_long(int64_t from)
752
return net_store_data((uchar*) buff,
753
(size_t) (int10_to_str((long int)from, buff,
754
(from <0)?-10:10)-buff));
758
bool Protocol_text::store_int64_t(int64_t from, bool unsigned_flag)
761
return net_store_data((uchar*) buff,
762
(size_t) (int64_t10_to_str(from,buff,
763
unsigned_flag ? 10 : -10)-
768
bool Protocol_text::store_decimal(const my_decimal *d)
770
char buff[DECIMAL_MAX_STR_LENGTH];
771
String str(buff, sizeof(buff), &my_charset_bin);
772
(void) my_decimal2string(E_DEC_FATAL_ERROR, d, 0, 0, 0, &str);
773
return net_store_data((uchar*) str.ptr(), str.length());
777
bool Protocol_text::store(float from, uint32_t decimals, String *buffer)
779
buffer->set_real((double) from, decimals, thd->charset());
780
return net_store_data((uchar*) buffer->ptr(), buffer->length());
784
bool Protocol_text::store(double from, uint32_t decimals, String *buffer)
786
buffer->set_real(from, decimals, thd->charset());
787
return net_store_data((uchar*) buffer->ptr(), buffer->length());
791
bool Protocol_text::store(Field *field)
793
if (field->is_null())
795
char buff[MAX_FIELD_WIDTH];
796
String str(buff,sizeof(buff), &my_charset_bin);
797
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
799
field->val_str(&str);
801
return store_string_aux(str.ptr(), str.length(), str.charset(), tocs);
807
Second_part format ("%06") needs to change when
808
we support 0-6 decimals for time.
811
bool Protocol_text::store(DRIZZLE_TIME *tm)
815
length= sprintf(buff, "%04d-%02d-%02d %02d:%02d:%02d",
823
length+= sprintf(buff+length, ".%06d",
824
(int)tm->second_part);
825
return net_store_data((uchar*) buff, length);
829
bool Protocol_text::store_date(DRIZZLE_TIME *tm)
831
char buff[MAX_DATE_STRING_REP_LENGTH];
832
size_t length= my_date_to_str(tm, buff);
833
return net_store_data((uchar*) buff, length);
839
Second_part format ("%06") needs to change when
840
we support 0-6 decimals for time.
843
bool Protocol_text::store_time(DRIZZLE_TIME *tm)
847
uint day= (tm->year || tm->month) ? 0 : tm->day;
848
length= sprintf(buff, "%s%02ld:%02d:%02d",
850
(long) day*24L+(long) tm->hour,
854
length+= sprintf(buff+length, ".%06d", (int)tm->second_part);
855
return net_store_data((uchar*) buff, length);