1
/* Copyright (C) 2008 Drizzle Open Source Project
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 */
17
This file is included by both libdrizzle.c (the DRIZZLE client C API)
18
and the drizzled server to connect to another DRIZZLE server.
20
The differences for the two cases are:
22
- Things that only works for the client:
23
- Trying to automaticly determinate user name if not supplied to
25
- Support for reading local file with LOAD DATA LOCAL
26
- SHARED memory handling
27
- Protection against sigpipe
30
- Things that only works for the server
31
- Alarm handling on connect
33
In all other cases, the code should be idential for the client and
37
#include <drizzled/global.h>
42
#include <sys/ioctl.h>
46
/* Remove client convenience wrappers */
47
#undef max_allowed_packet
48
#undef net_buffer_length
50
#define CLI_DRIZZLE_CONNECT drizzle_connect
52
#include <mysys/my_sys.h>
53
#include <mystrings/m_string.h>
54
#include <mystrings/m_ctype.h>
55
#include <drizzled/error.h>
57
#include <vio/violite.h>
66
#include <sys/socket.h>
67
#include <netinet/in.h>
68
#include <arpa/inet.h>
73
#ifdef HAVE_SYS_SELECT_H
74
#include <sys/select.h>
80
#define SOCKET_ERROR -1
82
#define CONNECT_TIMEOUT 0
84
#include "client_settings.h"
85
#include <drizzled/version.h>
86
#include <libdrizzle/sql_common.h>
89
char *drizzle_unix_port= 0;
90
const char *unknown_sqlstate= "HY000";
91
const char *not_error_sqlstate= "00000";
92
const char *cant_connect_sqlstate= "08001";
94
static bool drizzle_client_init= false;
95
static bool org_my_init_done= false;
97
static void drizzle_close_free_options(DRIZZLE *drizzle);
98
static void drizzle_close_free(DRIZZLE *drizzle);
100
static int wait_for_data(int fd, int32_t timeout);
101
int connect_with_timeout(int fd, const struct sockaddr *name, uint namelen, int32_t timeout);
103
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
105
/* Server error code and message */
106
unsigned int drizzle_server_last_errno;
107
char drizzle_server_last_error[DRIZZLE_ERRMSG_SIZE];
109
/****************************************************************************
110
A modified version of connect(). connect_with_timeout() allows you to specify
111
a timeout value, in seconds, that we should wait until we
112
derermine we can't connect to a particular host. If timeout is 0,
113
connect_with_timeout() will behave exactly like connect().
115
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
116
*****************************************************************************/
119
int connect_with_timeout(int fd, const struct sockaddr *name, uint namelen, int32_t timeout)
121
int flags, res, s_err;
124
If they passed us a timeout of zero, we should behave
125
exactly like the normal connect() call does.
129
return connect(fd, (struct sockaddr*) name, namelen);
131
flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
133
fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
136
res= connect(fd, (struct sockaddr*) name, namelen);
137
s_err= errno; /* Save the error... */
138
fcntl(fd, F_SETFL, flags);
139
if ((res != 0) && (s_err != EINPROGRESS))
141
errno= s_err; /* Restore it */
144
if (res == 0) /* Connected quickly! */
147
return wait_for_data(fd, timeout);
152
Wait up to timeout seconds for a connection to be established.
154
We prefer to do this with poll() as there is no limitations with this.
155
If not, we will use select()
158
static int wait_for_data(int fd, int32_t timeout)
164
ufds.events= POLLIN | POLLPRI;
165
if (!(res= poll(&ufds, 1, (int) timeout*1000)))
170
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)) || (ufds.revents & POLLHUP))
176
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
177
struct passwd *getpwuid(uid_t);
178
char* getlogin(void);
181
static void read_user_name(char *name)
184
strcpy(name,"root"); /* allow use of surun */
190
if ((str=getlogin()) == NULL)
192
if ((skr=getpwuid(geteuid())) != NULL)
194
else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
195
!(str=getenv("LOGIN")))
198
strncpy(name,str,USERNAME_LENGTH);
200
(void) cuserid(name);
202
strcpy(name,"UNKNOWN_USER");
210
Set the internal error message to DRIZZLE handler
212
@param drizzle connection handle (client side)
213
@param errcode CR_ error code, passed to ER macro to get
215
@parma sqlstate SQL standard sqlstate
218
void set_drizzle_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
221
assert(drizzle != 0);
226
net->last_errno= errcode;
227
strcpy(net->last_error, ER(errcode));
228
strcpy(net->sqlstate, sqlstate);
232
drizzle_server_last_errno= errcode;
233
strcpy(drizzle_server_last_error, ER(errcode));
239
Clear possible error state of struct NET
241
@param net clear the state of the argument
244
void net_clear_error(NET *net)
247
net->last_error[0]= '\0';
248
strcpy(net->sqlstate, not_error_sqlstate);
252
Set an error message on the client.
254
@param drizzle connection handle
255
@param errcode CR_* errcode, for client errors
256
@param sqlstate SQL standard sql state, unknown_sqlstate for the
257
majority of client errors.
258
@param format error message template, in sprintf format
259
@param ... variable number of arguments
262
static void set_drizzle_extended_error(DRIZZLE *drizzle, int errcode,
263
const char *sqlstate,
264
const char *format, ...)
268
assert(drizzle != 0);
271
net->last_errno= errcode;
272
va_start(args, format);
273
vsnprintf(net->last_error, sizeof(net->last_error)-1,
276
strcpy(net->sqlstate, sqlstate);
281
/*****************************************************************************
282
Read a packet from server. Give error message if socket was down
283
or packet is an error message
284
*****************************************************************************/
286
uint32_t cli_safe_read(DRIZZLE *drizzle)
288
NET *net= &drizzle->net;
290
init_sigpipe_variables
292
/* Don't give sigpipe errors if the client doesn't want them */
293
set_sigpipe(drizzle);
295
len=my_net_read(net);
296
reset_sigpipe(drizzle);
298
if (len == packet_error || len == 0)
300
#ifdef DRIZZLE_SERVER
301
if (net->vio && vio_was_interrupted(net->vio))
302
return (packet_error);
303
#endif /*DRIZZLE_SERVER*/
305
set_drizzle_error(drizzle, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
306
CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
307
return (packet_error);
309
if (net->read_pos[0] == 255)
313
char *pos=(char*) net->read_pos+1;
314
net->last_errno=uint2korr(pos);
319
strncpy(net->sqlstate, pos+1, SQLSTATE_LENGTH);
320
pos+= SQLSTATE_LENGTH+1;
325
The SQL state hasn't been received -- it should be reset to HY000
326
(unknown error sql state).
329
strcpy(net->sqlstate, unknown_sqlstate);
332
strncpy(net->last_error,(char*) pos, min((uint) len,
333
(uint32_t) sizeof(net->last_error)-1));
336
set_drizzle_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
338
Cover a protocol design error: error packet does not
339
contain the server status. Therefore, the client has no way
340
to find out whether there are more result sets of
341
a multiple-result-set statement pending. Luckily, in 5.0 an
342
error always aborts execution of a statement, wherever it is
343
a multi-statement or a stored procedure, so it should be
344
safe to unconditionally turn off the flag here.
346
drizzle->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
348
return(packet_error);
353
void free_rows(DRIZZLE_DATA *cur)
357
free_root(&cur->alloc,MYF(0));
358
my_free((uchar*) cur,MYF(0));
363
cli_advanced_command(DRIZZLE *drizzle, enum enum_server_command command,
364
const unsigned char *header, uint32_t header_length,
365
const unsigned char *arg, uint32_t arg_length, bool skip_check)
367
NET *net= &drizzle->net;
369
init_sigpipe_variables
370
bool stmt_skip= false;
372
/* Don't give sigpipe errors if the client doesn't want them */
373
set_sigpipe(drizzle);
375
if (drizzle->net.vio == 0)
376
{ /* Do reconnect if possible */
377
if (drizzle_reconnect(drizzle) || stmt_skip)
380
if (drizzle->status != DRIZZLE_STATUS_READY ||
381
drizzle->server_status & SERVER_MORE_RESULTS_EXISTS)
383
set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
387
net_clear_error(net);
389
drizzle->affected_rows= ~(uint64_t) 0;
391
We don't want to clear the protocol buffer on COM_QUIT, because if
392
the previous command was a shutdown command, we may have the
393
response for the COM_QUIT already in the communication buffer
395
net_clear(&drizzle->net, (command != COM_QUIT));
397
if (net_write_command(net,(uchar) command, header, header_length,
400
if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
402
set_drizzle_error(drizzle, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
406
if (drizzle_reconnect(drizzle) || stmt_skip)
408
if (net_write_command(net,(uchar) command, header, header_length,
411
set_drizzle_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
417
result= ((drizzle->packet_length=cli_safe_read(drizzle)) == packet_error ?
420
reset_sigpipe(drizzle);
424
void free_old_query(DRIZZLE *drizzle)
427
free_root(&drizzle->field_alloc,MYF(0));
428
init_alloc_root(&drizzle->field_alloc,8192,0); /* Assume rowlength < 8192 */
430
drizzle->field_count= 0; /* For API */
431
drizzle->warning_count= 0;
437
Flush result set sent from server
440
static void cli_flush_use_result(DRIZZLE *drizzle)
442
/* Clear the current execution status */
446
if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
448
if (pkt_len <= 8 && drizzle->net.read_pos[0] == DRIZZLE_PROTOCOL_NO_MORE_DATA)
450
char *pos= (char*) drizzle->net.read_pos + 1;
451
drizzle->warning_count=uint2korr(pos); pos+=2;
452
drizzle->server_status=uint2korr(pos); pos+=2;
454
break; /* End of data */
461
/**************************************************************************
463
**************************************************************************/
465
void end_server(DRIZZLE *drizzle)
467
int save_errno= errno;
468
if (drizzle->net.vio != 0)
470
init_sigpipe_variables
471
set_sigpipe(drizzle);
472
vio_delete(drizzle->net.vio);
473
reset_sigpipe(drizzle);
474
drizzle->net.vio= 0; /* Marker */
476
net_end(&drizzle->net);
477
free_old_query(drizzle);
483
drizzle_free_result(DRIZZLE_RES *result)
487
DRIZZLE *drizzle= result->handle;
490
if (drizzle->unbuffered_fetch_owner == &result->unbuffered_fetch_cancelled)
491
drizzle->unbuffered_fetch_owner= 0;
492
if (drizzle->status == DRIZZLE_STATUS_USE_RESULT)
494
(*drizzle->methods->flush_use_result)(drizzle);
495
drizzle->status=DRIZZLE_STATUS_READY;
496
if (drizzle->unbuffered_fetch_owner)
497
*drizzle->unbuffered_fetch_owner= true;
500
free_rows(result->data);
502
free_root(&result->field_alloc,MYF(0));
504
my_free((uchar*) result->row,MYF(0));
505
my_free((uchar*) result,MYF(0));
509
/****************************************************************************
510
Get options from my.cnf
511
****************************************************************************/
513
static const char *default_options[]=
515
"port","socket","compress","password","pipe", "timeout", "user",
516
"init-command", "host", "database", "return-found-rows",
517
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
518
"character-sets-dir", "default-character-set", "interactive-timeout",
519
"connect-timeout", "local-infile", "disable-local-infile",
520
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
521
"multi-results", "multi-statements", "multi-queries", "secure-auth",
522
"report-data-truncation",
526
static TYPELIB option_types={array_elements(default_options)-1,
527
"options",default_options, NULL};
529
const char *sql_protocol_names_lib[] =
530
{ "TCP", "SOCKET", "PIPE", "MEMORY", NullS };
531
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
532
sql_protocol_names_lib, NULL};
534
static int add_init_command(struct st_drizzle_options *options, const char *cmd)
538
if (!options->init_commands)
540
options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
542
init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
545
if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
546
insert_dynamic(options->init_commands, (uchar*)&tmp))
548
my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
555
void drizzle_read_default_options(struct st_drizzle_options *options,
556
const char *filename,const char *group)
559
char *argv_buff[1],**argv;
560
const char *groups[3];
562
argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
563
groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
565
load_defaults(filename, groups, &argc, &argv);
566
if (argc != 1) /* If some default option */
571
if (option[0][0] == '-' && option[0][1] == '-')
573
char *end=strrchr(*option,'=');
578
*end=0; /* Remove '=' */
580
/* Change all '_' in variable name to '-' */
581
for (end= *option ; *(end= strrchr(end,'_')) ; )
583
switch (find_type(*option+2,&option_types,2)) {
586
options->port=atoi(opt_arg);
591
my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
592
options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
595
case 3: /* compress */
597
options->client_flag|= CLIENT_COMPRESS;
599
case 4: /* password */
602
my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
603
options->password=my_strdup(opt_arg,MYF(MY_WME));
606
case 20: /* connect_timeout */
607
case 6: /* timeout */
609
options->connect_timeout=atoi(opt_arg);
614
my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
615
options->user=my_strdup(opt_arg,MYF(MY_WME));
618
case 8: /* init-command */
619
add_init_command(options,opt_arg);
624
my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
625
options->host=my_strdup(opt_arg,MYF(MY_WME));
628
case 10: /* database */
631
my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
632
options->db=my_strdup(opt_arg,MYF(MY_WME));
635
case 12: /* return-found-rows */
636
options->client_flag|=CLIENT_FOUND_ROWS;
638
case 13: /* Ignore SSL options */
644
case 17: /* charset-lib */
645
my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
646
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
649
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
650
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
652
case 19: /* Interactive-timeout */
653
options->client_flag|= CLIENT_INTERACTIVE;
656
if (!opt_arg || atoi(opt_arg) != 0)
657
options->client_flag|= CLIENT_LOCAL_FILES;
659
options->client_flag&= ~CLIENT_LOCAL_FILES;
662
options->client_flag&= ~CLIENT_LOCAL_FILES;
664
case 24: /* max-allowed-packet */
666
options->max_allowed_packet= atoi(opt_arg);
668
case 25: /* protocol */
669
if ((options->protocol= find_type(opt_arg,
670
&sql_protocol_typelib,0)) <= 0)
672
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
676
case 27: /* multi-results */
677
options->client_flag|= CLIENT_MULTI_RESULTS;
679
case 28: /* multi-statements */
680
case 29: /* multi-queries */
681
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
683
case 30: /* secure-auth */
684
options->secure_auth= true;
686
case 31: /* report-data-truncation */
687
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
700
/**************************************************************************
701
Get column lengths of the current row
702
If one uses drizzle_use_result, res->lengths contains the length information,
703
else the lengths are calculated from the offset between pointers.
704
**************************************************************************/
706
static void cli_fetch_lengths(uint32_t *to, DRIZZLE_ROW column, uint32_t field_count)
708
uint32_t *prev_length;
712
prev_length=0; /* Keep gcc happy */
713
for (end=column + field_count + 1 ; column != end ; column++, to++)
720
if (start) /* Found end of prev string */
721
*prev_length= (uint32_t) (*column-start-1);
727
/***************************************************************************
728
Change field rows to field structs
729
***************************************************************************/
732
unpack_fields(DRIZZLE_DATA *data, MEM_ROOT *alloc,uint fields,
736
DRIZZLE_FIELD *field,*result;
737
uint32_t lengths[9]; /* Max of fields */
739
field= result= (DRIZZLE_FIELD*) alloc_root(alloc,
740
(uint) sizeof(*field)*fields);
743
free_rows(data); /* Free old data */
746
memset((char*) field, 0, (uint) sizeof(DRIZZLE_FIELD)*fields);
748
for (row= data->data; row ; row = row->next,field++)
751
/* fields count may be wrong */
752
assert((uint) (field - result) < fields);
753
cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
754
field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]);
755
field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]);
756
field->table= strmake_root(alloc,(char*) row->data[2], lengths[2]);
757
field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]);
758
field->name= strmake_root(alloc,(char*) row->data[4], lengths[4]);
759
field->org_name= strmake_root(alloc,(char*) row->data[5], lengths[5]);
761
field->catalog_length= lengths[0];
762
field->db_length= lengths[1];
763
field->table_length= lengths[2];
764
field->org_table_length= lengths[3];
765
field->name_length= lengths[4];
766
field->org_name_length= lengths[5];
768
/* Unpack fixed length parts */
769
pos= (uchar*) row->data[6];
770
field->charsetnr= uint2korr(pos);
771
field->length= (uint) uint4korr(pos+2);
772
field->type= (enum enum_field_types) pos[6];
773
field->flags= uint2korr(pos+7);
774
field->decimals= (uint) pos[9];
776
if (INTERNAL_NUM_FIELD(field))
777
field->flags|= NUM_FLAG;
778
if (default_value && row->data[7])
780
field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]);
781
field->def_length= lengths[7];
785
field->max_length= 0;
788
free_rows(data); /* Free old data */
792
/* Read all rows (fields or data) from server */
794
DRIZZLE_DATA *cli_read_rows(DRIZZLE *drizzle, DRIZZLE_FIELD *DRIZZLE_FIELDs, uint32_t fields)
801
DRIZZLE_DATA *result;
802
DRIZZLE_ROWS **prev_ptr,*cur;
803
NET *net = &drizzle->net;
805
if ((pkt_len= cli_safe_read(drizzle)) == packet_error)
807
if (!(result=(DRIZZLE_DATA*) my_malloc(sizeof(DRIZZLE_DATA),
808
MYF(MY_WME | MY_ZEROFILL))))
810
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
813
init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
814
result->alloc.min_malloc=sizeof(DRIZZLE_ROWS);
815
prev_ptr= &result->data;
817
result->fields=fields;
820
The last EOF packet is either a 254 (0xFE) character followed by 1-7 status bytes.
822
This doesn't conflict with normal usage of 254 which stands for a
823
string where the length of the string is 8 bytes. (see net_field_length())
826
while (*(cp=net->read_pos) != DRIZZLE_PROTOCOL_NO_MORE_DATA || pkt_len >= 8)
829
if (!(cur= (DRIZZLE_ROWS*) alloc_root(&result->alloc,
830
sizeof(DRIZZLE_ROWS))) ||
831
!(cur->data= ((DRIZZLE_ROW)
832
alloc_root(&result->alloc,
833
(fields+1)*sizeof(char *)+pkt_len))))
836
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
840
prev_ptr= &cur->next;
841
to= (char*) (cur->data+fields+1);
843
for (field=0 ; field < fields ; field++)
845
if ((len= net_field_length(&cp)) == NULL_LENGTH)
847
cur->data[field] = 0;
851
cur->data[field] = to;
852
if (len > (uint32_t) (end_to - to))
855
set_drizzle_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
864
if (DRIZZLE_FIELDs[field].max_length < len)
865
DRIZZLE_FIELDs[field].max_length=len;
869
cur->data[field]=to; /* End of last field */
870
if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
876
*prev_ptr=0; /* last pointer is null */
877
if (pkt_len > 1) /* DRIZZLE 4.1 protocol */
879
drizzle->warning_count= uint2korr(cp+1);
880
drizzle->server_status= uint2korr(cp+3);
886
Read one row. Uses packet buffer as storage for fields.
887
When next packet is read, the previous field values are destroyed
892
read_one_row(DRIZZLE *drizzle, uint32_t fields, DRIZZLE_ROW row, uint32_t *lengths)
895
uint32_t pkt_len,len;
896
uchar *pos, *prev_pos, *end_pos;
897
NET *net= &drizzle->net;
899
if ((pkt_len=cli_safe_read(drizzle)) == packet_error)
901
if (pkt_len <= 8 && net->read_pos[0] == DRIZZLE_PROTOCOL_NO_MORE_DATA)
903
if (pkt_len > 1) /* DRIZZLE 4.1 protocol */
905
drizzle->warning_count= uint2korr(net->read_pos+1);
906
drizzle->server_status= uint2korr(net->read_pos+3);
908
return 1; /* End of data */
910
prev_pos= 0; /* allowed to write at packet[-1] */
913
for (field=0 ; field < fields ; field++)
915
if ((len= net_field_length(&pos)) == NULL_LENGTH)
922
if (len > (uint32_t) (end_pos - pos))
924
set_drizzle_error(drizzle, CR_UNKNOWN_ERROR, unknown_sqlstate);
927
row[field] = (char*) pos;
932
*prev_pos=0; /* Terminate prev field */
935
row[field]=(char*) prev_pos+1; /* End of last field */
936
*prev_pos=0; /* Terminate last field */
941
/****************************************************************************
942
Init DRIZZLE structure or allocate one
943
****************************************************************************/
946
drizzle_create(DRIZZLE *ptr)
949
if (!drizzle_client_init)
951
drizzle_client_init=true;
952
org_my_init_done=my_init_done;
954
/* Will init threads */
960
drizzle_port = DRIZZLE_PORT;
962
struct servent *serv_ptr;
966
if builder specifically requested a default port, use that
967
(even if it coincides with our factory default).
968
only if they didn't do we check /etc/services (and, failing
969
on that, fall back to the factory default of 4427).
970
either default can be overridden by the environment variable
971
DRIZZLE_TCP_PORT, which in turn can be overridden with command
975
#if DRIZZLE_PORT_DEFAULT == 0
976
if ((serv_ptr = getservbyname("drizzle", "tcp")))
977
drizzle_port = (uint) ntohs((ushort) serv_ptr->s_port);
979
if ((env = getenv("DRIZZLE_TCP_PORT")))
980
drizzle_port =(uint) atoi(env);
984
(void) signal(SIGPIPE, SIG_IGN);
988
/* Init if new thread */
989
if (my_thread_init())
994
ptr= (DRIZZLE *) malloc(sizeof(DRIZZLE));
998
set_drizzle_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
1001
memset(ptr, 0, sizeof(DRIZZLE));
1006
memset(ptr, 0, sizeof(DRIZZLE));
1009
ptr->options.connect_timeout= CONNECT_TIMEOUT;
1010
ptr->charset=default_client_charset_info;
1011
strcpy(ptr->net.sqlstate, not_error_sqlstate);
1014
Only enable LOAD DATA INFILE by default if configured with
1015
--enable-local-infile
1018
#if defined(ENABLED_LOCAL_INFILE) && !defined(DRIZZLE_SERVER)
1019
ptr->options.client_flag|= CLIENT_LOCAL_FILES;
1022
ptr->options.methods_to_use= DRIZZLE_OPT_GUESS_CONNECTION;
1023
ptr->options.report_data_truncation= true; /* default */
1026
By default we don't reconnect because it could silently corrupt data (after
1027
reconnection you potentially lose table locks, user variables, session
1028
variables (transactions but they are specifically dealt with in
1029
drizzle_reconnect()).
1030
This is a change: < 5.0.3 drizzle->reconnect was set to 1 by default.
1031
How this change impacts existing apps:
1032
- existing apps which relyed on the default will see a behaviour change;
1033
they will have to set reconnect=1 after drizzle_connect().
1034
- existing apps which explicitely asked for reconnection (the only way they
1035
could do it was by setting drizzle.reconnect to 1 after drizzle_connect())
1036
will not see a behaviour change.
1037
- existing apps which explicitely asked for no reconnection
1038
(drizzle.reconnect=0) will not see a behaviour change.
1047
Free all memory and resources used by the client library
1050
When calling this there should not be any other threads using
1053
To make things simpler when used with windows dll's (which calls this
1054
function automaticly), it's safe to call this function multiple times.
1058
void drizzle_server_end()
1060
if (!drizzle_client_init)
1065
/* If library called my_init(), free memory allocated by it */
1066
if (!org_my_init_done)
1073
drizzle_thread_end();
1076
drizzle_client_init= org_my_init_done= 0;
1077
#ifdef EMBEDDED_SERVER
1080
fclose(stderror_file);
1088
Fill in SSL part of DRIZZLE structure and set 'use_ssl' flag.
1089
NB! Errors are not reported until you do drizzle_connect.
1092
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
1095
Note that the drizzle argument must be initialized with drizzle_init()
1096
before calling drizzle_connect !
1099
static bool cli_read_query_result(DRIZZLE *drizzle);
1100
static DRIZZLE_RES *cli_use_result(DRIZZLE *drizzle);
1102
static DRIZZLE_METHODS client_methods=
1104
cli_read_query_result, /* read_query_result */
1105
cli_advanced_command, /* advanced_command */
1106
cli_read_rows, /* read_rows */
1107
cli_use_result, /* use_result */
1108
cli_fetch_lengths, /* fetch_lengths */
1109
cli_flush_use_result, /* flush_use_result */
1110
#ifndef DRIZZLE_SERVER
1111
cli_list_fields, /* list_fields */
1112
cli_unbuffered_fetch, /* unbuffered_fetch */
1113
cli_read_statistics, /* read_statistics */
1114
cli_read_query_result, /* next_result */
1115
cli_read_change_user_result, /* read_change_user_result */
1122
int drizzle_init_character_set(DRIZZLE *drizzle)
1124
const char *default_collation_name;
1126
/* Set character set */
1127
if (!drizzle->options.charset_name)
1129
default_collation_name= DRIZZLE_DEFAULT_COLLATION_NAME;
1130
if (!(drizzle->options.charset_name=
1131
my_strdup(DRIZZLE_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
1135
default_collation_name= NULL;
1138
const char *save= charsets_dir;
1139
if (drizzle->options.charset_dir)
1140
charsets_dir=drizzle->options.charset_dir;
1141
drizzle->charset=get_charset_by_csname(drizzle->options.charset_name,
1142
MY_CS_PRIMARY, MYF(MY_WME));
1143
if (drizzle->charset && default_collation_name)
1145
const CHARSET_INFO *collation;
1147
get_charset_by_name(default_collation_name, MYF(MY_WME))))
1149
if (!my_charset_same(drizzle->charset, collation))
1151
my_printf_error(ER_UNKNOWN_ERROR,
1152
"COLLATION %s is not valid for CHARACTER SET %s",
1154
default_collation_name, drizzle->options.charset_name);
1155
drizzle->charset= NULL;
1159
drizzle->charset= collation;
1163
drizzle->charset= NULL;
1168
if (!drizzle->charset)
1170
if (drizzle->options.charset_dir)
1171
set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
1172
ER(CR_CANT_READ_CHARSET),
1173
drizzle->options.charset_name,
1174
drizzle->options.charset_dir);
1177
char cs_dir_name[FN_REFLEN];
1178
get_charsets_dir(cs_dir_name);
1179
set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
1180
ER(CR_CANT_READ_CHARSET),
1181
drizzle->options.charset_name,
1192
CLI_DRIZZLE_CONNECT(DRIZZLE *drizzle,const char *host, const char *user,
1193
const char *passwd, const char *db,
1194
uint32_t port, const char *unix_socket, uint32_t client_flag)
1196
char buff[NAME_LEN+USERNAME_LENGTH+100];
1197
char *end,*host_info=NULL;
1198
uint32_t pkt_length;
1199
NET *net= &drizzle->net;
1200
init_sigpipe_variables
1202
/* Don't give sigpipe errors if the client doesn't want them */
1203
set_sigpipe(drizzle);
1204
drizzle->methods= &client_methods;
1205
net->vio = 0; /* If something goes wrong */
1206
drizzle->client_flag=0; /* For handshake */
1208
/* use default options */
1209
if (drizzle->options.my_cnf_file || drizzle->options.my_cnf_group)
1211
drizzle_read_default_options(&drizzle->options,
1212
(drizzle->options.my_cnf_file ?
1213
drizzle->options.my_cnf_file : "my"),
1214
drizzle->options.my_cnf_group);
1215
my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1216
my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1217
drizzle->options.my_cnf_file=drizzle->options.my_cnf_group=0;
1220
/* Some empty-string-tests are done because of ODBC */
1221
if (!host || !host[0])
1222
host=drizzle->options.host;
1223
if (!user || !user[0])
1225
user=drizzle->options.user;
1231
passwd=drizzle->options.password;
1236
db=drizzle->options.db;
1238
port=drizzle->options.port;
1240
unix_socket=drizzle->options.unix_socket;
1242
drizzle->server_status=SERVER_STATUS_AUTOCOMMIT;
1245
Part 0: Grab a socket and connect it to the server
1248
(!drizzle->options.protocol ||
1249
drizzle->options.protocol == DRIZZLE_PROTOCOL_TCP))
1251
struct addrinfo *res_lst, hints, *t_res;
1253
char port_buf[NI_MAXSERV];
1255
unix_socket=0; /* This is not used */
1263
snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
1265
memset(&hints, 0, sizeof(hints));
1266
hints.ai_socktype= SOCK_STREAM;
1268
snprintf(port_buf, NI_MAXSERV, "%d", port);
1269
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
1273
set_drizzle_extended_error(drizzle, CR_UNKNOWN_HOST, unknown_sqlstate,
1274
ER(CR_UNKNOWN_HOST), host, errno);
1279
for (t_res= res_lst; t_res != NULL; t_res= t_res->ai_next)
1281
int sock= socket(t_res->ai_family, t_res->ai_socktype,
1282
t_res->ai_protocol);
1283
if (sock == SOCKET_ERROR)
1286
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
1293
if (connect_with_timeout(sock, t_res->ai_addr, t_res->ai_addrlen, drizzle->options.connect_timeout))
1295
vio_delete(net->vio);
1302
freeaddrinfo(res_lst);
1307
set_drizzle_extended_error(drizzle, CR_CONN_HOST_ERROR, unknown_sqlstate,
1308
ER(CR_CONN_HOST_ERROR), host, socket_errno);
1312
if (my_net_init(net, net->vio))
1314
vio_delete(net->vio);
1316
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1319
vio_keepalive(net->vio,true);
1321
/* If user set read_timeout, let it override the default */
1322
if (drizzle->options.read_timeout)
1323
my_net_set_read_timeout(net, drizzle->options.read_timeout);
1325
/* If user set write_timeout, let it override the default */
1326
if (drizzle->options.write_timeout)
1327
my_net_set_write_timeout(net, drizzle->options.write_timeout);
1329
if (drizzle->options.max_allowed_packet)
1330
net->max_packet_size= drizzle->options.max_allowed_packet;
1332
/* Get version info */
1333
drizzle->protocol_version= PROTOCOL_VERSION; /* Assume this */
1334
if (drizzle->options.connect_timeout &&
1335
vio_poll_read(net->vio, drizzle->options.connect_timeout))
1337
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1338
ER(CR_SERVER_LOST_EXTENDED),
1339
"waiting for initial communication packet",
1345
Part 1: Connection established, read and parse first packet
1348
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
1350
if (drizzle->net.last_errno == CR_SERVER_LOST)
1351
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1352
ER(CR_SERVER_LOST_EXTENDED),
1353
"reading initial communication packet",
1357
/* Check if version of protocol matches current one */
1359
drizzle->protocol_version= net->read_pos[0];
1360
if (drizzle->protocol_version != PROTOCOL_VERSION)
1362
set_drizzle_extended_error(drizzle, CR_VERSION_ERROR, unknown_sqlstate,
1363
ER(CR_VERSION_ERROR), drizzle->protocol_version,
1367
end=strend((char*) net->read_pos+1);
1368
drizzle->thread_id=uint4korr(end+1);
1371
Scramble is split into two parts because old clients does not understand
1372
long scrambles; here goes the first part.
1374
strncpy(drizzle->scramble, end, SCRAMBLE_LENGTH_323);
1375
end+= SCRAMBLE_LENGTH_323+1;
1377
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
1378
drizzle->server_capabilities=uint2korr(end);
1379
if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
1381
/* New protocol with 16 bytes to describe server characteristics */
1382
drizzle->server_language=end[2];
1383
drizzle->server_status=uint2korr(end+3);
1386
if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
1387
(char *) net->read_pos))
1388
strncpy(drizzle->scramble+SCRAMBLE_LENGTH_323, end,
1389
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
1391
drizzle->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
1393
if (drizzle->options.secure_auth && passwd[0] &&
1394
!(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
1396
set_drizzle_error(drizzle, CR_SECURE_AUTH, unknown_sqlstate);
1400
if (drizzle_init_character_set(drizzle))
1403
/* Save connection information */
1404
if (!my_multi_malloc(MYF(0),
1405
&drizzle->host_info, (uint) strlen(host_info)+1,
1406
&drizzle->host, (uint) strlen(host)+1,
1407
&drizzle->unix_socket,unix_socket ?
1408
(uint) strlen(unix_socket)+1 : (uint) 1,
1409
&drizzle->server_version,
1410
(uint) (end - (char*) net->read_pos),
1412
!(drizzle->user=my_strdup(user,MYF(0))) ||
1413
!(drizzle->passwd=my_strdup(passwd,MYF(0))))
1415
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1418
strcpy(drizzle->host_info,host_info);
1419
strcpy(drizzle->host,host);
1421
strcpy(drizzle->unix_socket,unix_socket);
1423
drizzle->unix_socket=0;
1424
strcpy(drizzle->server_version,(char*) net->read_pos+1);
1428
Part 2: format and send client info to the server for access check
1431
client_flag|=drizzle->options.client_flag;
1432
client_flag|=CLIENT_CAPABILITIES;
1433
if (client_flag & CLIENT_MULTI_STATEMENTS)
1434
client_flag|= CLIENT_MULTI_RESULTS;
1437
client_flag|=CLIENT_CONNECT_WITH_DB;
1439
/* Remove options that server doesn't support */
1440
client_flag= ((client_flag &
1441
~(CLIENT_COMPRESS | CLIENT_SSL)) |
1442
(client_flag & drizzle->server_capabilities));
1443
client_flag&= ~CLIENT_COMPRESS;
1445
int4store(buff, client_flag);
1446
int4store(buff+4, net->max_packet_size);
1447
buff[8]= (char) drizzle->charset->number;
1448
memset(buff+9, 0, 32-9);
1451
drizzle->client_flag=client_flag;
1453
/* This needs to be changed as it's not useful with big packets */
1454
if (user && user[0])
1455
strncpy(end,user,USERNAME_LENGTH); /* Max user name */
1457
read_user_name((char*) end);
1459
/* We have to handle different version of handshake here */
1460
end= strend(end) + 1;
1464
*end++= SCRAMBLE_LENGTH;
1465
memset(end, 0, SCRAMBLE_LENGTH-1);
1466
memcpy(end, passwd, strlen(passwd));
1467
end+= SCRAMBLE_LENGTH;
1471
*end++= '\0'; /* empty password */
1473
/* Add database if needed */
1474
if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
1476
end= strncpy(end, db, NAME_LEN) + NAME_LEN + 1;
1477
drizzle->db= my_strdup(db,MYF(MY_WME));
1480
/* Write authentication package */
1481
if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
1483
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1484
ER(CR_SERVER_LOST_EXTENDED),
1485
"sending authentication information",
1491
Part 3: Authorization data's been sent. Now server can reply with
1492
OK-packet, or re-request scrambled password.
1495
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
1497
if (drizzle->net.last_errno == CR_SERVER_LOST)
1498
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1499
ER(CR_SERVER_LOST_EXTENDED),
1500
"reading authorization packet",
1505
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
1509
if (db && drizzle_select_db(drizzle, db))
1511
if (drizzle->net.last_errno == CR_SERVER_LOST)
1512
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1513
ER(CR_SERVER_LOST_EXTENDED),
1514
"Setting intital database",
1519
if (drizzle->options.init_commands)
1521
DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
1522
char **ptr= (char**)init_commands->buffer;
1523
char **end_command= ptr + init_commands->elements;
1525
bool reconnect=drizzle->reconnect;
1526
drizzle->reconnect=0;
1528
for (; ptr < end_command; ptr++)
1531
if (drizzle_real_query(drizzle,*ptr, (uint32_t) strlen(*ptr)))
1533
if (drizzle->fields)
1535
if (!(res= cli_use_result(drizzle)))
1537
drizzle_free_result(res);
1540
drizzle->reconnect=reconnect;
1543
reset_sigpipe(drizzle);
1547
reset_sigpipe(drizzle);
1549
/* Free alloced memory */
1550
end_server(drizzle);
1551
drizzle_close_free(drizzle);
1552
if (!(((uint32_t) client_flag) & CLIENT_REMEMBER_OPTIONS))
1553
drizzle_close_free_options(drizzle);
1559
bool drizzle_reconnect(DRIZZLE *drizzle)
1561
DRIZZLE tmp_drizzle;
1564
if (!drizzle->reconnect ||
1565
(drizzle->server_status & SERVER_STATUS_IN_TRANS) || !drizzle->host_info)
1567
/* Allow reconnect next time */
1568
drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
1569
set_drizzle_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
1572
drizzle_create(&tmp_drizzle);
1573
tmp_drizzle.options= drizzle->options;
1574
tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
1576
if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
1577
drizzle->db, drizzle->port, drizzle->unix_socket,
1578
drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
1580
drizzle->net.last_errno= tmp_drizzle.net.last_errno;
1581
strcpy(drizzle->net.last_error, tmp_drizzle.net.last_error);
1582
strcpy(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
1585
if (drizzle_set_character_set(&tmp_drizzle, drizzle->charset->csname))
1587
memset(&tmp_drizzle.options, 0, sizeof(tmp_drizzle.options));
1588
drizzle_close(&tmp_drizzle);
1589
drizzle->net.last_errno= tmp_drizzle.net.last_errno;
1590
strcpy(drizzle->net.last_error, tmp_drizzle.net.last_error);
1591
strcpy(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
1595
tmp_drizzle.reconnect= 1;
1596
tmp_drizzle.free_me= drizzle->free_me;
1598
/* Don't free options as these are now used in tmp_drizzle */
1599
memset(&drizzle->options, 0, sizeof(drizzle->options));
1601
drizzle_close(drizzle);
1602
*drizzle=tmp_drizzle;
1603
net_clear(&drizzle->net, 1);
1604
drizzle->affected_rows= ~(uint64_t) 0;
1609
/**************************************************************************
1610
Set current database
1611
**************************************************************************/
1614
drizzle_select_db(DRIZZLE *drizzle, const char *db)
1618
if ((error=simple_command(drizzle,COM_INIT_DB, (const uchar*) db,
1619
(uint32_t) strlen(db),0)))
1621
my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
1622
drizzle->db=my_strdup(db,MYF(MY_WME));
1627
/*************************************************************************
1628
Send a QUIT to the server and close the connection
1629
If handle is alloced by DRIZZLE connect free it.
1630
*************************************************************************/
1632
static void drizzle_close_free_options(DRIZZLE *drizzle)
1634
my_free(drizzle->options.user,MYF(MY_ALLOW_ZERO_PTR));
1635
my_free(drizzle->options.host,MYF(MY_ALLOW_ZERO_PTR));
1636
my_free(drizzle->options.password,MYF(MY_ALLOW_ZERO_PTR));
1637
my_free(drizzle->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
1638
my_free(drizzle->options.db,MYF(MY_ALLOW_ZERO_PTR));
1639
my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1640
my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1641
my_free(drizzle->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
1642
my_free(drizzle->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
1643
my_free(drizzle->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
1644
if (drizzle->options.init_commands)
1646
DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
1647
char **ptr= (char**)init_commands->buffer;
1648
char **end= ptr + init_commands->elements;
1649
for (; ptr<end; ptr++)
1650
my_free(*ptr,MYF(MY_WME));
1651
delete_dynamic(init_commands);
1652
my_free((char*)init_commands,MYF(MY_WME));
1654
memset(&drizzle->options, 0, sizeof(drizzle->options));
1659
static void drizzle_close_free(DRIZZLE *drizzle)
1661
my_free((uchar*) drizzle->host_info,MYF(MY_ALLOW_ZERO_PTR));
1662
my_free(drizzle->user,MYF(MY_ALLOW_ZERO_PTR));
1663
my_free(drizzle->passwd,MYF(MY_ALLOW_ZERO_PTR));
1664
my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
1665
my_free(drizzle->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
1666
drizzle->info_buffer= 0;
1668
/* Clear pointers for better safety */
1669
drizzle->host_info= drizzle->user= drizzle->passwd= drizzle->db= 0;
1673
void drizzle_close(DRIZZLE *drizzle)
1675
if (drizzle) /* Some simple safety */
1677
/* If connection is still up, send a QUIT message */
1678
if (drizzle->net.vio != 0)
1680
free_old_query(drizzle);
1681
drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
1682
drizzle->reconnect=0;
1683
simple_command(drizzle,COM_QUIT,(uchar*) 0,0,1);
1684
end_server(drizzle); /* Sets drizzle->net.vio= 0 */
1686
drizzle_close_free_options(drizzle);
1687
drizzle_close_free(drizzle);
1688
if (drizzle->free_me)
1689
my_free((uchar*) drizzle,MYF(0));
1695
static bool cli_read_query_result(DRIZZLE *drizzle)
1698
uint32_t field_count;
1699
DRIZZLE_DATA *fields;
1702
if ((length = cli_safe_read(drizzle)) == packet_error)
1704
free_old_query(drizzle); /* Free old result */
1705
#ifdef DRIZZLE_CLIENT /* Avoid warn of unused labels*/
1708
pos=(uchar*) drizzle->net.read_pos;
1709
if ((field_count= net_field_length(&pos)) == 0)
1711
drizzle->affected_rows= net_field_length_ll(&pos);
1712
drizzle->insert_id= net_field_length_ll(&pos);
1714
drizzle->server_status= uint2korr(pos); pos+=2;
1715
drizzle->warning_count= uint2korr(pos); pos+=2;
1717
if (pos < drizzle->net.read_pos+length && net_field_length(&pos))
1718
drizzle->info=(char*) pos;
1721
#ifdef DRIZZLE_CLIENT
1722
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
1726
if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
1728
set_drizzle_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
1732
error= handle_local_infile(drizzle,(char*) pos);
1733
if ((length= cli_safe_read(drizzle)) == packet_error || error)
1735
goto get_info; /* Get info packet */
1738
if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
1739
drizzle->server_status|= SERVER_STATUS_IN_TRANS;
1741
if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, 7)))
1743
if (!(drizzle->fields= unpack_fields(fields,&drizzle->field_alloc,
1744
(uint) field_count, 0)))
1746
drizzle->status= DRIZZLE_STATUS_GET_RESULT;
1747
drizzle->field_count= (uint) field_count;
1753
Send the query and return so we can do something else.
1754
Needs to be followed by drizzle_read_query_result() when we want to
1755
finish processing it.
1759
drizzle_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
1761
return(simple_command(drizzle, COM_QUERY, (uchar*) query, length, 1));
1766
drizzle_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
1768
if (drizzle_send_query(drizzle,query,length))
1770
return((int) (*drizzle->methods->read_query_result)(drizzle));
1774
/**************************************************************************
1775
Alloc result struct for buffered results. All rows are read to buffer.
1776
drizzle_data_seek may be used.
1777
**************************************************************************/
1779
DRIZZLE_RES * drizzle_store_result(DRIZZLE *drizzle)
1781
DRIZZLE_RES *result;
1783
if (!drizzle->fields)
1785
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
1787
set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
1790
drizzle->status=DRIZZLE_STATUS_READY; /* server is ready */
1791
if (!(result=(DRIZZLE_RES*) my_malloc((uint) (sizeof(DRIZZLE_RES)+
1793
drizzle->field_count),
1794
MYF(MY_WME | MY_ZEROFILL))))
1796
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1799
result->methods= drizzle->methods;
1800
result->eof= 1; /* Marker for buffered */
1801
result->lengths= (uint32_t*) (result+1);
1803
(*drizzle->methods->read_rows)(drizzle,drizzle->fields,drizzle->field_count)))
1805
my_free((uchar*) result,MYF(0));
1808
drizzle->affected_rows= result->row_count= result->data->rows;
1809
result->data_cursor= result->data->data;
1810
result->fields= drizzle->fields;
1811
result->field_alloc= drizzle->field_alloc;
1812
result->field_count= drizzle->field_count;
1813
/* The rest of result members is zeroed in malloc */
1814
drizzle->fields=0; /* fields is now in result */
1815
clear_alloc_root(&drizzle->field_alloc);
1816
/* just in case this was mistakenly called after drizzle_stmt_execute() */
1817
drizzle->unbuffered_fetch_owner= 0;
1818
return(result); /* Data fetched */
1822
/**************************************************************************
1823
Alloc struct for use with unbuffered reads. Data is fetched by domand
1824
when calling to drizzle_fetch_row.
1825
DRIZZLE_DATA_seek is a noop.
1827
No other queries may be specified with the same DRIZZLE handle.
1828
There shouldn't be much processing per row because DRIZZLE server shouldn't
1829
have to wait for the client (and will not wait more than 30 sec/packet).
1830
**************************************************************************/
1832
static DRIZZLE_RES * cli_use_result(DRIZZLE *drizzle)
1834
DRIZZLE_RES *result;
1836
if (!drizzle->fields)
1838
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
1840
set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
1843
if (!(result=(DRIZZLE_RES*) my_malloc(sizeof(*result)+
1844
sizeof(uint32_t)*drizzle->field_count,
1845
MYF(MY_WME | MY_ZEROFILL))))
1847
result->lengths=(uint32_t*) (result+1);
1848
result->methods= drizzle->methods;
1849
if (!(result->row=(DRIZZLE_ROW)
1850
my_malloc(sizeof(result->row[0])*(drizzle->field_count+1), MYF(MY_WME))))
1851
{ /* Ptrs: to one row */
1852
my_free((uchar*) result,MYF(0));
1855
result->fields= drizzle->fields;
1856
result->field_alloc= drizzle->field_alloc;
1857
result->field_count= drizzle->field_count;
1858
result->current_field=0;
1859
result->handle= drizzle;
1860
result->current_row= 0;
1861
drizzle->fields=0; /* fields is now in result */
1862
clear_alloc_root(&drizzle->field_alloc);
1863
drizzle->status=DRIZZLE_STATUS_USE_RESULT;
1864
drizzle->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
1865
return(result); /* Data is read to be fetched */
1869
/**************************************************************************
1870
Return next row of the query results
1871
**************************************************************************/
1874
drizzle_fetch_row(DRIZZLE_RES *res)
1877
{ /* Unbufferred fetch */
1880
DRIZZLE *drizzle= res->handle;
1881
if (drizzle->status != DRIZZLE_STATUS_USE_RESULT)
1883
set_drizzle_error(drizzle,
1884
res->unbuffered_fetch_cancelled ?
1885
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
1888
else if (!(read_one_row(drizzle, res->field_count, res->row, res->lengths)))
1891
return(res->current_row=res->row);
1894
drizzle->status=DRIZZLE_STATUS_READY;
1896
Reset only if owner points to us: there is a chance that somebody
1897
started new query after drizzle_stmt_close():
1899
if (drizzle->unbuffered_fetch_owner == &res->unbuffered_fetch_cancelled)
1900
drizzle->unbuffered_fetch_owner= 0;
1901
/* Don't clear handle in drizzle_free_result */
1904
return((DRIZZLE_ROW) NULL);
1908
if (!res->data_cursor)
1910
return(res->current_row=(DRIZZLE_ROW) NULL);
1912
tmp = res->data_cursor->data;
1913
res->data_cursor = res->data_cursor->next;
1914
return(res->current_row=tmp);
1919
/**************************************************************************
1920
Get column lengths of the current row
1921
If one uses drizzle_use_result, res->lengths contains the length information,
1922
else the lengths are calculated from the offset between pointers.
1923
**************************************************************************/
1926
drizzle_fetch_lengths(DRIZZLE_RES *res)
1930
if (!(column=res->current_row))
1931
return 0; /* Something is wrong */
1933
(*res->methods->fetch_lengths)(res->lengths, column, res->field_count);
1934
return res->lengths;
1939
drizzle_options(DRIZZLE *drizzle,enum drizzle_option option, const void *arg)
1942
case DRIZZLE_OPT_CONNECT_TIMEOUT:
1943
drizzle->options.connect_timeout= *(uint*) arg;
1945
case DRIZZLE_OPT_READ_TIMEOUT:
1946
drizzle->options.read_timeout= *(uint*) arg;
1948
case DRIZZLE_OPT_WRITE_TIMEOUT:
1949
drizzle->options.write_timeout= *(uint*) arg;
1951
case DRIZZLE_OPT_COMPRESS:
1952
drizzle->options.compress= 1; /* Remember for connect */
1953
drizzle->options.client_flag|= CLIENT_COMPRESS;
1955
case DRIZZLE_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
1956
if (!arg || test(*(uint*) arg))
1957
drizzle->options.client_flag|= CLIENT_LOCAL_FILES;
1959
drizzle->options.client_flag&= ~CLIENT_LOCAL_FILES;
1961
case DRIZZLE_INIT_COMMAND:
1962
add_init_command(&drizzle->options,arg);
1964
case DRIZZLE_READ_DEFAULT_FILE:
1965
my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1966
drizzle->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
1968
case DRIZZLE_READ_DEFAULT_GROUP:
1969
my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1970
drizzle->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
1972
case DRIZZLE_SET_CHARSET_DIR:
1973
my_free(drizzle->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
1974
drizzle->options.charset_dir=my_strdup(arg,MYF(MY_WME));
1976
case DRIZZLE_SET_CHARSET_NAME:
1977
my_free(drizzle->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
1978
drizzle->options.charset_name=my_strdup(arg,MYF(MY_WME));
1980
case DRIZZLE_OPT_PROTOCOL:
1981
drizzle->options.protocol= *(const uint*) arg;
1983
case DRIZZLE_OPT_USE_REMOTE_CONNECTION:
1984
case DRIZZLE_OPT_GUESS_CONNECTION:
1985
drizzle->options.methods_to_use= option;
1987
case DRIZZLE_SET_CLIENT_IP:
1988
drizzle->options.client_ip= my_strdup(arg, MYF(MY_WME));
1990
case DRIZZLE_SECURE_AUTH:
1991
drizzle->options.secure_auth= *(const bool *) arg;
1993
case DRIZZLE_REPORT_DATA_TRUNCATION:
1994
drizzle->options.report_data_truncation= test(*(const bool *) arg);
1996
case DRIZZLE_OPT_RECONNECT:
1997
drizzle->reconnect= *(const bool *) arg;
1999
case DRIZZLE_OPT_SSL_VERIFY_SERVER_CERT:
2000
if (*(const bool*) arg)
2001
drizzle->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
2003
drizzle->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
2012
/****************************************************************************
2013
Functions to get information from the DRIZZLE structure
2014
These are functions to make shared libraries more usable.
2015
****************************************************************************/
2018
uint64_t drizzle_num_rows(const DRIZZLE_RES *res)
2020
return res->row_count;
2023
unsigned int drizzle_num_fields(const DRIZZLE_RES *res)
2025
return res->field_count;
2028
uint drizzle_errno(const DRIZZLE *drizzle)
2030
return drizzle ? drizzle->net.last_errno : drizzle_server_last_errno;
2034
const char * drizzle_error(const DRIZZLE *drizzle)
2036
return drizzle ? _(drizzle->net.last_error) : _(drizzle_server_last_error);
2041
Get version number for server in a form easy to test on
2044
drizzle_get_server_version()
2051
We will ensure that a newer server always has a bigger number.
2054
Signed number > 323000
2058
drizzle_get_server_version(const DRIZZLE *drizzle)
2060
uint major, minor, version;
2061
char *pos= drizzle->server_version, *end_pos;
2062
major= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
2063
minor= (uint) strtoul(pos, &end_pos, 10); pos=end_pos+1;
2064
version= (uint) strtoul(pos, &end_pos, 10);
2065
return (uint32_t) major*10000L+(uint32_t) (minor*100+version);
2070
drizzle_set_character_set function sends SET NAMES cs_name to
2071
the server (which changes character_set_client, character_set_result
2072
and character_set_connection) and updates drizzle->charset so other
2073
functions like drizzle_real_escape will work correctly.
2075
int drizzle_set_character_set(DRIZZLE *drizzle, const char *cs_name)
2077
const CHARSET_INFO *cs;
2078
const char *save_csdir= charsets_dir;
2080
if (drizzle->options.charset_dir)
2081
charsets_dir= drizzle->options.charset_dir;
2083
if (strlen(cs_name) < MY_CS_NAME_SIZE &&
2084
(cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
2086
char buff[MY_CS_NAME_SIZE + 10];
2087
charsets_dir= save_csdir;
2088
sprintf(buff, "SET NAMES %s", cs_name);
2089
if (!drizzle_real_query(drizzle, buff, strlen(buff)))
2091
drizzle->charset= cs;
2096
char cs_dir_name[FN_REFLEN];
2097
get_charsets_dir(cs_dir_name);
2098
set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
2099
ER(CR_CANT_READ_CHARSET), cs_name, cs_dir_name);
2101
charsets_dir= save_csdir;
2102
return drizzle->net.last_errno;