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, Inc.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <drizzled/global.h>
24
#include <drizzled/common.h>
25
#include <libdrizzle/libdrizzle.h>
26
#include <libdrizzle/pack.h>
27
#include <libdrizzle/errmsg.h>
28
#include <libdrizzle/drizzle.h>
29
#include <drizzled/gettext.h>
30
#include <libdrizzle/net_serv.h>
31
#include <libdrizzle/drizzle_data.h>
32
#include <libdrizzle/local_infile.h>
34
#include "libdrizzle_priv.h"
43
#include <sys/socket.h>
46
#define CONNECT_TIMEOUT 0
48
static bool drizzle_client_init= false;
49
unsigned int drizzle_server_last_errno;
51
/* Server error code and message */
52
char drizzle_server_last_error[LIBDRIZZLE_ERRMSG_SIZE];
55
Note that the drizzle argument must be initialized with drizzle_init()
56
before calling drizzle_connect !
61
static DRIZZLE_METHODS client_methods=
63
cli_read_query_result, /* read_query_result */
64
cli_advanced_command, /* advanced_command */
65
cli_read_rows, /* read_rows */
66
cli_use_result, /* use_result */
67
cli_fetch_lengths, /* fetch_lengths */
68
cli_flush_use_result, /* flush_use_result */
69
cli_list_fields, /* list_fields */
70
cli_unbuffered_fetch, /* unbuffered_fetch */
71
cli_read_statistics, /* read_statistics */
72
cli_read_query_result, /* next_result */
73
cli_read_change_user_result, /* read_change_user_result */
78
/****************************************************************************
79
Init DRIZZLE structure or allocate one
80
****************************************************************************/
83
drizzle_create(DRIZZLE *ptr)
86
if (!drizzle_client_init)
88
drizzle_client_init=true;
90
if (!drizzle_get_default_port())
92
drizzle_set_default_port(DRIZZLE_PORT);
94
struct servent *serv_ptr;
98
if builder specifically requested a default port, use that
99
(even if it coincides with our factory default).
100
only if they didn't do we check /etc/services (and, failing
101
on that, fall back to the factory default of 4427).
102
either default can be overridden by the environment variable
103
DRIZZLE_TCP_PORT, which in turn can be overridden with command
107
#if DRIZZLE_PORT_DEFAULT == 0
108
if ((serv_ptr = getservbyname("drizzle", "tcp")))
109
drizzle_set_default_port((uint32_t) ntohs((uint16_t) serv_ptr->s_port));
111
if ((env = getenv("DRIZZLE_TCP_PORT")))
112
drizzle_set_default_port((uint32_t) atoi(env));
116
(void) signal(SIGPIPE, SIG_IGN);
122
ptr= (DRIZZLE *) malloc(sizeof(DRIZZLE));
126
drizzle_set_error(NULL, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
129
memset(ptr, 0, sizeof(DRIZZLE));
134
memset(ptr, 0, sizeof(DRIZZLE));
137
ptr->options.connect_timeout= CONNECT_TIMEOUT;
138
strcpy(ptr->net.sqlstate, sqlstate_get_not_error());
141
Only enable LOAD DATA INFILE by default if configured with
142
--enable-local-infile
145
#if defined(ENABLED_LOCAL_INFILE)
146
ptr->options.client_flag|= CLIENT_LOCAL_FILES;
149
ptr->options.methods_to_use= DRIZZLE_OPT_GUESS_CONNECTION;
150
ptr->options.report_data_truncation= true; /* default */
153
By default we don't reconnect because it could silently corrupt data (after
154
reconnection you potentially lose table locks, user variables, session
155
variables (transactions but they are specifically dealt with in
156
drizzle_reconnect()).
157
This is a change: < 5.0.3 drizzle->reconnect was set to 1 by default.
158
How this change impacts existing apps:
159
- existing apps which relyed on the default will see a behaviour change;
160
they will have to set reconnect=1 after drizzle_connect().
161
- existing apps which explicitely asked for reconnection (the only way they
162
could do it was by setting drizzle.reconnect to 1 after drizzle_connect())
163
will not see a behaviour change.
164
- existing apps which explicitely asked for no reconnection
165
(drizzle.reconnect=0) will not see a behaviour change.
173
static void read_user_name(char *name)
176
strcpy(name,"root"); /* allow use of surun */
182
if ((str=getlogin()) == NULL)
184
if ((skr=getpwuid(geteuid())) != NULL)
186
else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
187
!(str=getenv("LOGIN")))
190
strncpy(name,str,USERNAME_LENGTH);
192
(void) cuserid(name);
194
strcpy(name,"UNKNOWN_USER");
201
drizzle_connect(DRIZZLE *drizzle,const char *host, const char *user,
202
const char *passwd, const char *db,
204
const char * unix_port __attribute__((__unused__)),
205
uint32_t client_flag)
207
char buff[NAME_LEN+USERNAME_LENGTH+100];
208
char *end,*host_info=NULL;
210
NET *net= &drizzle->net;
212
drizzle->methods= &client_methods;
213
net->vio = 0; /* If something goes wrong */
214
drizzle->client_flag=0; /* For handshake */
216
/* Some empty-string-tests are done because of ODBC */
217
if (!host || !host[0])
218
host=drizzle->options.host;
219
if (!user || !user[0])
221
user=drizzle->options.user;
227
passwd=drizzle->options.password;
232
db=drizzle->options.db;
234
port=drizzle->options.port;
236
drizzle->server_status=SERVER_STATUS_AUTOCOMMIT;
239
Part 0: Grab a socket and connect it to the server
243
struct addrinfo *res_lst, hints, *t_res;
245
char port_buf[NI_MAXSERV];
248
port= drizzle_get_default_port();
253
snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
255
memset(&hints, 0, sizeof(hints));
256
hints.ai_socktype= SOCK_STREAM;
258
snprintf(port_buf, NI_MAXSERV, "%d", port);
259
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
263
drizzle_set_extended_error(drizzle, CR_UNKNOWN_HOST, sqlstate_get_unknown(),
264
ER(CR_UNKNOWN_HOST), host, errno);
269
for (t_res= res_lst; t_res != NULL; t_res= t_res->ai_next)
271
int sock= socket(t_res->ai_family, t_res->ai_socktype,
276
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
283
if (connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
285
vio_delete(net->vio);
292
freeaddrinfo(res_lst);
297
drizzle_set_extended_error(drizzle, CR_CONN_HOST_ERROR, sqlstate_get_unknown(),
298
ER(CR_CONN_HOST_ERROR), host, errno);
302
if (my_net_init(net, net->vio))
304
vio_delete(net->vio);
306
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
309
vio_keepalive(net->vio,true);
311
/* If user set read_timeout, let it override the default */
312
if (drizzle->options.read_timeout)
313
my_net_set_read_timeout(net, drizzle->options.read_timeout);
315
/* If user set write_timeout, let it override the default */
316
if (drizzle->options.write_timeout)
317
my_net_set_write_timeout(net, drizzle->options.write_timeout);
319
if (drizzle->options.max_allowed_packet)
320
net->max_packet_size= drizzle->options.max_allowed_packet;
322
/* Get version info */
323
drizzle->protocol_version= PROTOCOL_VERSION; /* Assume this */
324
if (drizzle->options.connect_timeout &&
325
vio_poll_read(net->vio, drizzle->options.connect_timeout))
327
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
328
ER(CR_SERVER_LOST_INITIAL_COMM_WAIT),
334
Part 1: Connection established, read and parse first packet
337
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
339
if (drizzle->net.last_errno == CR_SERVER_LOST)
340
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
341
ER(CR_SERVER_LOST_INITIAL_COMM_READ),
345
/* Check if version of protocol matches current one */
347
drizzle->protocol_version= net->read_pos[0];
348
if (drizzle->protocol_version != PROTOCOL_VERSION)
350
drizzle_set_extended_error(drizzle, CR_VERSION_ERROR, sqlstate_get_unknown(),
351
ER(CR_VERSION_ERROR), drizzle->protocol_version,
355
end= strchr((char*) net->read_pos+1, '\0');
356
drizzle->thread_id=uint4korr(end+1);
359
Scramble is split into two parts because old clients does not understand
360
long scrambles; here goes the first part.
362
strncpy(drizzle->scramble, end, SCRAMBLE_LENGTH_323);
363
end+= SCRAMBLE_LENGTH_323+1;
365
if (pkt_length >= (uint32_t) (end+1 - (char*) net->read_pos))
366
drizzle->server_capabilities=uint2korr(end);
367
if (pkt_length >= (uint32_t) (end+18 - (char*) net->read_pos))
369
/* New protocol with 16 bytes to describe server characteristics */
370
drizzle->server_language=end[2];
371
drizzle->server_status=uint2korr(end+3);
374
if (pkt_length >= (uint32_t) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
375
(char *) net->read_pos))
376
strncpy(drizzle->scramble+SCRAMBLE_LENGTH_323, end,
377
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
379
drizzle->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
381
if (drizzle->options.secure_auth && passwd[0] &&
382
!(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
384
drizzle_set_error(drizzle, CR_SECURE_AUTH, sqlstate_get_unknown());
388
/* Save connection information */
389
if (!(drizzle->host_info= (char *)malloc(strlen(host_info)+1+strlen(host)+1
390
+(end - (char*) net->read_pos))) ||
391
!(drizzle->user=strdup(user)) ||
392
!(drizzle->passwd=strdup(passwd)))
394
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
397
drizzle->host= drizzle->host_info+strlen(host_info)+1;
398
drizzle->server_version= drizzle->host+strlen(host)+1;
399
strcpy(drizzle->host_info,host_info);
400
strcpy(drizzle->host,host);
401
strcpy(drizzle->server_version,(char*) net->read_pos+1);
405
Part 2: format and send client info to the server for access check
408
client_flag|=drizzle->options.client_flag;
409
client_flag|=CLIENT_CAPABILITIES;
410
if (client_flag & CLIENT_MULTI_STATEMENTS)
411
client_flag|= CLIENT_MULTI_RESULTS;
414
client_flag|=CLIENT_CONNECT_WITH_DB;
416
/* Remove options that server doesn't support */
417
client_flag= ((client_flag &
418
~(CLIENT_COMPRESS | CLIENT_SSL)) |
419
(client_flag & drizzle->server_capabilities));
420
client_flag&= ~CLIENT_COMPRESS;
422
int4store(buff, client_flag);
423
int4store(buff+4, net->max_packet_size);
424
buff[8]= (char) 45; // utf8 charset number
425
memset(buff+9, 0, 32-9);
428
drizzle->client_flag=client_flag;
430
/* This needs to be changed as it's not useful with big packets */
432
strncpy(end,user,USERNAME_LENGTH); /* Max user name */
434
read_user_name((char*) end);
436
/* We have to handle different version of handshake here */
437
end= strchr(end, '\0') + 1;
441
*end++= SCRAMBLE_LENGTH;
442
memset(end, 0, SCRAMBLE_LENGTH-1);
443
memcpy(end, passwd, strlen(passwd));
444
end+= SCRAMBLE_LENGTH;
448
*end++= '\0'; /* empty password */
450
/* Add database if needed */
451
if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
453
size_t db_len= strlen(db);
455
if (db_len >= NAME_LEN)
456
db_len= NAME_LEN - 1;
457
end= memcpy(end, db, db_len);
461
drizzle->db= strdup(db);
464
/* Write authentication package */
465
if (my_net_write(net, (unsigned char*) buff, (size_t) (end-buff)) || net_flush(net))
467
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
468
ER(CR_SERVER_LOST_SEND_AUTH),
474
Part 3: Authorization data's been sent. Now server can reply with
475
OK-packet, or re-request scrambled password.
478
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
480
if (drizzle->net.last_errno == CR_SERVER_LOST)
481
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
482
ER(CR_SERVER_LOST_READ_AUTH),
487
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
491
if (db && drizzle_select_db(drizzle, db))
493
if (drizzle->net.last_errno == CR_SERVER_LOST)
494
drizzle_set_extended_error(drizzle, CR_SERVER_LOST, sqlstate_get_unknown(),
495
ER(CR_SERVER_LOST_SETTING_DB),
505
/* Free alloced memory */
506
drizzle_disconnect(drizzle);
507
drizzle_close_free(drizzle);
508
if (!(((uint32_t) client_flag) & CLIENT_REMEMBER_OPTIONS))
509
drizzle_close_free_options(drizzle);
517
/**************************************************************************
519
**************************************************************************/
522
drizzle_select_db(DRIZZLE *drizzle, const char *db)
526
if ((error=simple_command(drizzle,COM_INIT_DB, (const unsigned char*) db,
527
(uint32_t) strlen(db),0)))
529
if (drizzle->db != NULL)
531
drizzle->db=strdup(db);
535
bool drizzle_reconnect(DRIZZLE *drizzle)
540
if (!drizzle->reconnect ||
541
(drizzle->server_status & SERVER_STATUS_IN_TRANS) || !drizzle->host_info)
543
/* Allow reconnect next time */
544
drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
545
drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, sqlstate_get_unknown());
548
drizzle_create(&tmp_drizzle);
549
tmp_drizzle.options= drizzle->options;
550
tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
552
if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
553
drizzle->db, drizzle->port, 0,
554
drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
556
drizzle->net.last_errno= tmp_drizzle.net.last_errno;
557
strcpy(drizzle->net.last_error, tmp_drizzle.net.last_error);
558
strcpy(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
562
tmp_drizzle.reconnect= 1;
563
tmp_drizzle.free_me= drizzle->free_me;
565
/* Don't free options as these are now used in tmp_drizzle */
566
memset(&drizzle->options, 0, sizeof(drizzle->options));
568
drizzle_close(drizzle);
569
*drizzle=tmp_drizzle;
570
net_clear(&drizzle->net, 1);
571
drizzle->affected_rows= ~(uint64_t) 0;
575
/**************************************************************************
577
**************************************************************************/
579
void drizzle_disconnect(DRIZZLE *drizzle)
581
int save_errno= errno;
582
if (drizzle->net.vio != 0)
584
vio_delete(drizzle->net.vio);
585
drizzle->net.vio= 0; /* Marker */
587
net_end(&drizzle->net);
588
free_old_query(drizzle);
593
/*************************************************************************
594
Send a QUIT to the server and close the connection
595
If handle is alloced by DRIZZLE connect free it.
596
*************************************************************************/
598
void drizzle_close_free_options(DRIZZLE *drizzle)
600
if (drizzle->options.user != NULL)
601
free(drizzle->options.user);
602
if (drizzle->options.host != NULL)
603
free(drizzle->options.host);
604
if (drizzle->options.password != NULL)
605
free(drizzle->options.password);
606
if (drizzle->options.db != NULL)
607
free(drizzle->options.db);
608
if (drizzle->options.my_cnf_file != NULL)
609
free(drizzle->options.my_cnf_file);
610
if (drizzle->options.my_cnf_group != NULL)
611
free(drizzle->options.my_cnf_group);
612
if (drizzle->options.client_ip != NULL)
613
free(drizzle->options.client_ip);
614
memset(&drizzle->options, 0, sizeof(drizzle->options));
619
void drizzle_close_free(DRIZZLE *drizzle)
621
if (drizzle->host_info != NULL)
622
free((unsigned char*) drizzle->host_info);
623
if (drizzle->user != NULL)
625
if (drizzle->passwd != NULL)
626
free(drizzle->passwd);
627
if (drizzle->db != NULL)
629
if (drizzle->info_buffer != NULL)
630
free(drizzle->info_buffer);
631
drizzle->info_buffer= 0;
633
/* Clear pointers for better safety */
634
drizzle->host_info= drizzle->user= drizzle->passwd= drizzle->db= 0;
638
void drizzle_close(DRIZZLE *drizzle)
640
if (drizzle) /* Some simple safety */
642
/* If connection is still up, send a QUIT message */
643
if (drizzle->net.vio != 0)
645
free_old_query(drizzle);
646
drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
647
drizzle->reconnect=0;
648
simple_command(drizzle,COM_QUIT,(unsigned char*) 0,0,1);
649
drizzle_disconnect(drizzle); /* Sets drizzle->net.vio= 0 */
651
drizzle_close_free_options(drizzle);
652
drizzle_close_free(drizzle);
653
if (drizzle->free_me)
654
free((unsigned char*) drizzle);
660
bool cli_read_query_result(DRIZZLE *drizzle)
663
uint32_t field_count;
664
DRIZZLE_DATA *fields;
667
if ((length = cli_safe_read(drizzle)) == packet_error)
669
free_old_query(drizzle); /* Free old result */
671
pos=(unsigned char*) drizzle->net.read_pos;
672
if ((field_count= net_field_length(&pos)) == 0)
674
drizzle->affected_rows= net_field_length_ll(&pos);
675
drizzle->insert_id= net_field_length_ll(&pos);
677
drizzle->server_status= uint2korr(pos); pos+=2;
678
drizzle->warning_count= uint2korr(pos); pos+=2;
680
if (pos < drizzle->net.read_pos+length && net_field_length(&pos))
681
drizzle->info=(char*) pos;
684
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
688
if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
690
drizzle_set_error(drizzle, CR_MALFORMED_PACKET, sqlstate_get_unknown());
694
error= handle_local_infile(drizzle,(char*) pos);
695
if ((length= cli_safe_read(drizzle)) == packet_error || error)
697
goto get_info; /* Get info packet */
699
if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
700
drizzle->server_status|= SERVER_STATUS_IN_TRANS;
702
if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, 7)))
704
if (!(drizzle->fields= unpack_fields(fields, (uint32_t) field_count, 0)))
706
drizzle->status= DRIZZLE_STATUS_GET_RESULT;
707
drizzle->field_count= (uint32_t) field_count;
713
Send the query and return so we can do something else.
714
Needs to be followed by drizzle_read_query_result() when we want to
715
finish processing it.
719
drizzle_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
721
return(simple_command(drizzle, COM_QUERY, (unsigned char*) query, length, 1));
726
drizzle_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
728
if (drizzle_send_query(drizzle,query,length))
730
return((int) (*drizzle->methods->read_query_result)(drizzle));
734
/**************************************************************************
735
Alloc result struct for buffered results. All rows are read to buffer.
736
drizzle_data_seek may be used.
737
**************************************************************************/
739
DRIZZLE_RES * drizzle_store_result(DRIZZLE *drizzle)
743
if (!drizzle->fields)
745
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
747
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
750
drizzle->status=DRIZZLE_STATUS_READY; /* server is ready */
751
if (!(result=(DRIZZLE_RES*) malloc((uint32_t) (sizeof(DRIZZLE_RES)+
753
drizzle->field_count))))
755
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
758
memset(result, 0,(sizeof(DRIZZLE_RES)+ sizeof(uint32_t) *
759
drizzle->field_count));
760
result->methods= drizzle->methods;
761
result->eof= 1; /* Marker for buffered */
762
result->lengths= (uint32_t*) (result+1);
764
(*drizzle->methods->read_rows)(drizzle,drizzle->fields,drizzle->field_count)))
766
free((unsigned char*) result);
769
drizzle->affected_rows= result->row_count= result->data->rows;
770
result->data_cursor= result->data->data;
771
result->fields= drizzle->fields;
772
result->field_count= drizzle->field_count;
773
/* The rest of result members is zeroed in malloc */
774
drizzle->fields=0; /* fields is now in result */
775
/* just in case this was mistakenly called after drizzle_stmt_execute() */
776
drizzle->unbuffered_fetch_owner= 0;
777
return(result); /* Data fetched */
781
/**************************************************************************
782
Alloc struct for use with unbuffered reads. Data is fetched by domand
783
when calling to drizzle_fetch_row.
784
DRIZZLE_DATA_seek is a noop.
786
No other queries may be specified with the same DRIZZLE handle.
787
There shouldn't be much processing per row because DRIZZLE server shouldn't
788
have to wait for the client (and will not wait more than 30 sec/packet).
789
**************************************************************************/
791
DRIZZLE_RES * cli_use_result(DRIZZLE *drizzle)
795
if (!drizzle->fields)
797
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
799
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, sqlstate_get_unknown());
802
if (!(result=(DRIZZLE_RES*) malloc(sizeof(*result)+
803
sizeof(uint32_t)*drizzle->field_count)))
805
memset(result, 0, sizeof(*result)+ sizeof(uint32_t)*drizzle->field_count);
806
result->lengths=(uint32_t*) (result+1);
807
result->methods= drizzle->methods;
808
if (!(result->row=(DRIZZLE_ROW)
809
malloc(sizeof(result->row[0])*(drizzle->field_count+1))))
810
{ /* Ptrs: to one row */
811
free((unsigned char*) result);
814
result->fields= drizzle->fields;
815
result->field_count= drizzle->field_count;
816
result->current_field=0;
817
result->handle= drizzle;
818
result->current_row= 0;
819
drizzle->fields=0; /* fields is now in result */
820
drizzle->status=DRIZZLE_STATUS_USE_RESULT;
821
drizzle->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
822
return(result); /* Data is read to be fetched */
828
Set the internal error message to DRIZZLE handler
830
@param drizzle connection handle (client side)
831
@param errcode CR_ error code, passed to ER macro to get
833
@parma sqlstate SQL standard sqlstate
836
void drizzle_set_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
839
assert(drizzle != 0);
844
net->last_errno= errcode;
845
strcpy(net->last_error, ER(errcode));
846
strcpy(net->sqlstate, sqlstate);
850
drizzle_server_last_errno= errcode;
851
strcpy(drizzle_server_last_error, ER(errcode));
857
unsigned int drizzle_errno(const DRIZZLE *drizzle)
859
return drizzle ? drizzle->net.last_errno : drizzle_server_last_errno;
863
const char * drizzle_error(const DRIZZLE *drizzle)
865
return drizzle ? _(drizzle->net.last_error) : _(drizzle_server_last_error);
869
Set an error message on the client.
871
@param drizzle connection handle
872
@param errcode CR_* errcode, for client errors
873
@param sqlstate SQL standard sql state, sqlstate_get_unknown() for the
874
majority of client errors.
875
@param format error message template, in sprintf format
876
@param ... variable number of arguments
879
void drizzle_set_extended_error(DRIZZLE *drizzle, int errcode,
880
const char *sqlstate,
881
const char *format, ...)
885
assert(drizzle != 0);
888
net->last_errno= errcode;
889
va_start(args, format);
890
vsnprintf(net->last_error, sizeof(net->last_error)-1,
893
strcpy(net->sqlstate, sqlstate);
901
Flush result set sent from server
904
void cli_flush_use_result(DRIZZLE *drizzle)
906
/* Clear the current execution status */
910
if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
912
if (pkt_len <= 8 && drizzle->net.read_pos[0] == DRIZZLE_PROTOCOL_NO_MORE_DATA)
914
char *pos= (char*) drizzle->net.read_pos + 1;
915
drizzle->warning_count=uint2korr(pos); pos+=2;
916
drizzle->server_status=uint2korr(pos); pos+=2;
918
break; /* End of data */
924
/**************************************************************************
925
Get column lengths of the current row
926
If one uses drizzle_use_result, res->lengths contains the length information,
927
else the lengths are calculated from the offset between pointers.
928
**************************************************************************/
930
void cli_fetch_lengths(uint32_t *to, DRIZZLE_ROW column, uint32_t field_count)
932
uint32_t *prev_length;
936
prev_length=0; /* Keep gcc happy */
937
for (end=column + field_count + 1 ; column != end ; column++, to++)
944
if (start) /* Found end of prev string */
945
*prev_length= (uint32_t) (*column-start-1);