72
87
#ifdef HAVE_SYS_SELECT_H
73
88
#include <sys/select.h>
90
#endif /*!defined(MSDOS) && !defined(__WIN__) */
95
#if defined(MSDOS) || defined(__WIN__)
79
99
#define SOCKET_ERROR -1
82
#include <drizzled/version.h>
83
#include <libdrizzle/sql_common.h>
84
#include <libdrizzle/gettext.h>
85
#include "local_infile.h"
94
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
95
struct passwd *getpwuid(uid_t);
103
#define CONNECT_TIMEOUT 20
105
#define CONNECT_TIMEOUT 0
108
#include "client_settings.h"
109
#include <sql_common.h>
112
char *mysql_unix_port= 0;
113
const char *unknown_sqlstate= "HY000";
114
const char *not_error_sqlstate= "00000";
115
const char *cant_connect_sqlstate= "08001";
117
char *shared_memory_base_name= 0;
118
const char *def_shared_memory_base_name= default_shared_memory_base_name;
121
static void mysql_close_free_options(MYSQL *mysql);
122
static void mysql_close_free(MYSQL *mysql);
124
#if !(defined(__WIN__) || defined(__NETWARE__))
125
static int wait_for_data(my_socket fd, uint timeout);
128
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
130
/* Server error code and message */
131
unsigned int mysql_server_last_errno;
132
char mysql_server_last_error[MYSQL_ERRMSG_SIZE];
134
/****************************************************************************
135
A modified version of connect(). my_connect() allows you to specify
136
a timeout value, in seconds, that we should wait until we
137
derermine we can't connect to a particular host. If timeout is 0,
138
my_connect() will behave exactly like connect().
140
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
141
*****************************************************************************/
143
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
146
#if defined(__WIN__) || defined(__NETWARE__)
147
return connect(fd, (struct sockaddr*) name, namelen);
149
int flags, res, s_err;
152
If they passed us a timeout of zero, we should behave
153
exactly like the normal connect() call does.
157
return connect(fd, (struct sockaddr*) name, namelen);
159
flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
161
fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
164
res= connect(fd, (struct sockaddr*) name, namelen);
165
s_err= errno; /* Save the error... */
166
fcntl(fd, F_SETFL, flags);
167
if ((res != 0) && (s_err != EINPROGRESS))
169
errno= s_err; /* Restore it */
172
if (res == 0) /* Connected quickly! */
174
return wait_for_data(fd, timeout);
180
Wait up to timeout seconds for a connection to be established.
182
We prefer to do this with poll() as there is no limitations with this.
183
If not, we will use select()
186
#if !(defined(__WIN__) || defined(__NETWARE__))
188
static int wait_for_data(my_socket fd, uint timeout)
195
ufds.events= POLLIN | POLLPRI;
196
if (!(res= poll(&ufds, 1, (int) timeout*1000)))
201
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
205
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
208
time_t start_time, now_time;
211
if (fd >= FD_SETSIZE) /* Check if wrong error */
212
return 0; /* Can't use timeout */
215
Our connection is "in progress." We can use the select() call to wait
216
up to a specified period of time for the connection to suceed.
217
If select() returns 0 (after waiting howevermany seconds), our socket
218
never became writable (host is probably unreachable.) Otherwise, if
219
select() returns 1, then one of two conditions exist:
221
1. An error occured. We use getsockopt() to check for this.
222
2. The connection was set up sucessfully: getsockopt() will
223
return 0 as an error.
225
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
226
who posted this method of timing out a connect() in
227
comp.unix.programmer on August 15th, 1997.
233
select could be interrupted by a signal, and if it is,
234
the timeout should be adjusted and the select restarted
235
to work around OSes that don't restart select and
236
implementations of select that don't adjust tv upon
237
failure to reflect the time remaining
239
start_time= my_time(0);
242
tv.tv_sec = (long) timeout;
245
if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
248
if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
251
if (res == 0) /* timeout */
253
now_time= my_time(0);
254
timeout-= (uint) (now_time - start_time);
255
if (errno != EINTR || (int) timeout <= 0)
260
select() returned something more interesting than zero, let's
261
see if we have any errors. If the next two statements pass,
262
we've got an open socket!
266
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
270
{ /* getsockopt could succeed */
272
return(-1); /* but return an error... */
275
#endif /* HAVE_POLL */
277
#endif /* defined(__WIN__) || defined(__NETWARE__) */
280
Set the internal error message to mysql handler
282
@param mysql connection handle (client side)
283
@param errcode CR_ error code, passed to ER macro to get
285
@parma sqlstate SQL standard sqlstate
288
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
291
DBUG_ENTER("set_mysql_error");
292
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
293
DBUG_ASSERT(mysql != 0);
298
net->last_errno= errcode;
299
strmov(net->last_error, ER(errcode));
300
strmov(net->sqlstate, sqlstate);
304
mysql_server_last_errno= errcode;
305
strmov(mysql_server_last_error, ER(errcode));
311
Clear possible error state of struct NET
313
@param net clear the state of the argument
316
void net_clear_error(NET *net)
319
net->last_error[0]= '\0';
320
strmov(net->sqlstate, not_error_sqlstate);
324
Set an error message on the client.
326
@param mysql connection handle
327
@param errcode CR_* errcode, for client errors
328
@param sqlstate SQL standard sql state, unknown_sqlstate for the
329
majority of client errors.
330
@param format error message template, in sprintf format
331
@param ... variable number of arguments
334
static void set_mysql_extended_error(MYSQL *mysql, int errcode,
335
const char *sqlstate,
336
const char *format, ...)
340
DBUG_ENTER("set_mysql_extended_error");
341
DBUG_PRINT("enter", ("error :%d '%s'", errcode, format));
342
DBUG_ASSERT(mysql != 0);
345
net->last_errno= errcode;
346
va_start(args, format);
347
my_vsnprintf(net->last_error, sizeof(net->last_error)-1,
350
strmov(net->sqlstate, sqlstate);
358
Create a named pipe connection
363
HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
364
char **arg_unix_socket)
366
HANDLE hPipe=INVALID_HANDLE_VALUE;
367
char pipe_name[1024];
370
my_bool testing_named_pipes=0;
371
char *host= *arg_host, *unix_socket= *arg_unix_socket;
373
if ( ! unix_socket || (unix_socket)[0] == 0x00)
374
unix_socket = mysql_unix_port;
375
if (!host || !strcmp(host,LOCAL_HOST))
376
host=LOCAL_HOST_NAMEDPIPE;
379
pipe_name[sizeof(pipe_name)-1]= 0; /* Safety if too long string */
380
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\", host, "\\pipe\\",
382
DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s", host, unix_socket));
384
for (i=0 ; i < 100 ; i++) /* Don't retry forever */
386
if ((hPipe = CreateFile(pipe_name,
387
GENERIC_READ | GENERIC_WRITE,
392
NULL )) != INVALID_HANDLE_VALUE)
394
if (GetLastError() != ERROR_PIPE_BUSY)
396
set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR,
397
unknown_sqlstate, ER(CR_NAMEDPIPEOPEN_ERROR),
398
host, unix_socket, (ulong) GetLastError());
399
return INVALID_HANDLE_VALUE;
401
/* wait for for an other instance */
402
if (! WaitNamedPipe(pipe_name, connect_timeout*1000) )
404
set_mysql_extended_error(mysql, CR_NAMEDPIPEWAIT_ERROR, unknown_sqlstate,
405
ER(CR_NAMEDPIPEWAIT_ERROR),
406
host, unix_socket, (ulong) GetLastError());
407
return INVALID_HANDLE_VALUE;
410
if (hPipe == INVALID_HANDLE_VALUE)
412
set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR, unknown_sqlstate,
413
ER(CR_NAMEDPIPEOPEN_ERROR), host, unix_socket,
414
(ulong) GetLastError());
415
return INVALID_HANDLE_VALUE;
417
dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
418
if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
420
CloseHandle( hPipe );
421
set_mysql_extended_error(mysql, CR_NAMEDPIPESETSTATE_ERROR,
422
unknown_sqlstate, ER(CR_NAMEDPIPESETSTATE_ERROR),
423
host, unix_socket, (ulong) GetLastError());
424
return INVALID_HANDLE_VALUE;
426
*arg_host=host ; *arg_unix_socket=unix_socket; /* connect arg */
433
Create new shared memory connection, return handler of connection
436
create_shared_memory()
437
mysql Pointer of mysql structure
438
net Pointer of net structure
439
connect_timeout Timeout of connection
443
HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
445
ulong smem_buffer_length = shared_memory_buffer_length + 4;
447
event_connect_request is event object for start connection actions
448
event_connect_answer is event object for confirm, that server put data
449
handle_connect_file_map is file-mapping object, use for create shared
451
handle_connect_map is pointer on shared memory
452
handle_map is pointer on shared memory for client
456
event_client_read are events for transfer data between server and client
457
handle_file_map is file-mapping object, use for create shared memory
459
HANDLE event_connect_request = NULL;
460
HANDLE event_connect_answer = NULL;
461
HANDLE handle_connect_file_map = NULL;
462
char *handle_connect_map = NULL;
464
char *handle_map = NULL;
465
HANDLE event_server_wrote = NULL;
466
HANDLE event_server_read = NULL;
467
HANDLE event_client_wrote = NULL;
468
HANDLE event_client_read = NULL;
469
HANDLE event_conn_closed = NULL;
470
HANDLE handle_file_map = NULL;
471
ulong connect_number;
472
char connect_number_char[22], *p;
475
DWORD error_allow = 0;
476
DWORD error_code = 0;
477
DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE;
478
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
481
get enough space base-name + '_' + longest suffix we might ever send
483
if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
487
The name of event and file-mapping events create agree next rule:
488
shared_memory_base_name+unique_part
490
shared_memory_base_name is unique value for each server
491
unique_part is uniquel value for each object (events and file-mapping)
493
suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", NullS);
494
strmov(suffix_pos, "CONNECT_REQUEST");
495
if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp)))
497
error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
500
strmov(suffix_pos, "CONNECT_ANSWER");
501
if (!(event_connect_answer= OpenEvent(event_access_rights,FALSE,tmp)))
503
error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
506
strmov(suffix_pos, "CONNECT_DATA");
507
if (!(handle_connect_file_map= OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)))
509
error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
512
if (!(handle_connect_map= MapViewOfFile(handle_connect_file_map,
513
FILE_MAP_WRITE,0,0,sizeof(DWORD))))
515
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
519
/* Send to server request of connection */
520
if (!SetEvent(event_connect_request))
522
error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
526
/* Wait of answer from server */
527
if (WaitForSingleObject(event_connect_answer,connect_timeout*1000) !=
530
error_allow = CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR;
534
/* Get number of connection */
535
connect_number = uint4korr(handle_connect_map);/*WAX2*/
536
p= int10_to_str(connect_number, connect_number_char, 10);
539
The name of event and file-mapping events create agree next rule:
540
shared_memory_base_name+unique_part+number_of_connection
543
shared_memory_base_name is uniquel value for each server
544
unique_part is uniquel value for each object (events and file-mapping)
545
number_of_connection is number of connection between server and client
547
suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", connect_number_char,
549
strmov(suffix_pos, "DATA");
550
if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
552
error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
555
if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,
556
smem_buffer_length)) == NULL)
558
error_allow = CR_SHARED_MEMORY_MAP_ERROR;
562
strmov(suffix_pos, "SERVER_WROTE");
563
if ((event_server_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
565
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
569
strmov(suffix_pos, "SERVER_READ");
570
if ((event_server_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
572
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
576
strmov(suffix_pos, "CLIENT_WROTE");
577
if ((event_client_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
579
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
583
strmov(suffix_pos, "CLIENT_READ");
584
if ((event_client_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
586
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
590
strmov(suffix_pos, "CONNECTION_CLOSED");
591
if ((event_conn_closed = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
593
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
597
Set event that server should send data
599
SetEvent(event_server_read);
602
if (error_allow == 0)
604
net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
606
event_server_read,event_client_wrote,
607
event_client_read,event_conn_closed);
611
error_code = GetLastError();
612
if (event_server_read)
613
CloseHandle(event_server_read);
614
if (event_server_wrote)
615
CloseHandle(event_server_wrote);
616
if (event_client_read)
617
CloseHandle(event_client_read);
618
if (event_client_wrote)
619
CloseHandle(event_client_wrote);
620
if (event_conn_closed)
621
CloseHandle(event_conn_closed);
623
UnmapViewOfFile(handle_map);
625
CloseHandle(handle_file_map);
629
my_free(tmp, MYF(0));
631
error_code = GetLastError();
632
if (event_connect_request)
633
CloseHandle(event_connect_request);
634
if (event_connect_answer)
635
CloseHandle(event_connect_answer);
636
if (handle_connect_map)
637
UnmapViewOfFile(handle_connect_map);
638
if (handle_connect_file_map)
639
CloseHandle(handle_connect_file_map);
642
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
643
set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
644
ER(error_allow), suffix_pos, error_code);
646
set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
647
ER(error_allow), error_code);
648
return(INVALID_HANDLE_VALUE);
101
654
/*****************************************************************************
102
655
Read a packet from server. Give error message if socket was down
103
656
or packet is an error message
104
657
*****************************************************************************/
106
uint32_t cli_safe_read(DRIZZLE *drizzle)
660
cli_safe_read(MYSQL *mysql)
108
NET *net= &drizzle->net;
662
NET *net= &mysql->net;
664
init_sigpipe_variables
666
/* Don't give sigpipe errors if the client doesn't want them */
111
668
if (net->vio != 0)
112
669
len=my_net_read(net);
670
reset_sigpipe(mysql);
114
672
if (len == packet_error || len == 0)
116
#ifdef DRIZZLE_SERVER
674
DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %lu",
675
vio_description(net->vio),len));
117
677
if (net->vio && vio_was_interrupted(net->vio))
118
678
return (packet_error);
119
#endif /*DRIZZLE_SERVER*/
120
drizzle_disconnect(drizzle);
121
drizzle_set_error(drizzle, net->last_errno == CR_NET_PACKET_TOO_LARGE ?
122
CR_NET_PACKET_TOO_LARGE : CR_SERVER_LOST,
123
sqlstate_get_unknown());
679
#endif /*MYSQL_SERVER*/
681
set_mysql_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
682
CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
124
683
return (packet_error);
126
685
if (net->read_pos[0] == 255)
160
719
a multi-statement or a stored procedure, so it should be
161
720
safe to unconditionally turn off the flag here.
163
drizzle->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
722
mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
724
DBUG_PRINT("error",("Got error: %d/%s (%s)",
165
728
return(packet_error);
171
cli_advanced_command(DRIZZLE *drizzle, enum enum_server_command command,
172
const unsigned char *header, uint32_t header_length,
173
const unsigned char *arg, uint32_t arg_length, bool skip_check)
175
NET *net= &drizzle->net;
177
bool stmt_skip= false;
179
if (drizzle->net.vio == 0)
180
{ /* Do reconnect if possible */
181
if (drizzle_reconnect(drizzle) || stmt_skip)
184
if (drizzle->status != DRIZZLE_STATUS_READY ||
185
drizzle->server_status & SERVER_MORE_RESULTS_EXISTS)
187
drizzle_set_error(drizzle, CR_COMMANDS_OUT_OF_SYNC,
188
sqlstate_get_unknown());
733
void free_rows(MYSQL_DATA *cur)
737
free_root(&cur->alloc,MYF(0));
738
my_free((uchar*) cur,MYF(0));
743
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
744
const uchar *header, ulong header_length,
745
const uchar *arg, ulong arg_length, my_bool skip_check)
747
NET *net= &mysql->net;
749
init_sigpipe_variables
750
my_bool stmt_skip= FALSE;
751
DBUG_ENTER("cli_advanced_command");
753
/* Don't give sigpipe errors if the client doesn't want them */
756
if (mysql->net.vio == 0)
757
{ /* Do reconnect if possible */
758
if (mysql_reconnect(mysql) || stmt_skip)
761
if (mysql->status != MYSQL_STATUS_READY ||
762
mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
764
DBUG_PRINT("error",("state: %d", mysql->status));
765
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
192
769
net_clear_error(net);
194
drizzle->affected_rows= ~(uint64_t) 0;
771
mysql->affected_rows= ~(my_ulonglong) 0;
196
773
We don't want to clear the protocol buffer on COM_QUIT, because if
197
774
the previous command was a shutdown command, we may have the
198
775
response for the COM_QUIT already in the communication buffer
200
net_clear(&drizzle->net, (command != COM_QUIT));
777
net_clear(&mysql->net, (command != COM_QUIT));
202
if (net_write_command(net,(unsigned char) command, header, header_length,
779
if (net_write_command(net,(uchar) command, header, header_length,
205
if (net->last_errno == CR_NET_PACKET_TOO_LARGE)
782
DBUG_PRINT("error",("Can't send command to server. Error: %d",
784
if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
207
drizzle_set_error(drizzle, CR_NET_PACKET_TOO_LARGE, sqlstate_get_unknown());
786
set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
210
drizzle_disconnect(drizzle);
211
if (drizzle_reconnect(drizzle) || stmt_skip)
790
if (mysql_reconnect(mysql) || stmt_skip)
213
if (net_write_command(net,(unsigned char) command, header, header_length,
792
if (net_write_command(net,(uchar) command, header, header_length,
216
drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, sqlstate_get_unknown());
795
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
222
result= ((drizzle->packet_length=cli_safe_read(drizzle)) == packet_error ?
801
result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ?
228
void free_old_query(DRIZZLE *drizzle)
232
/* TODO - we need to de-alloc field storage */
233
free(drizzle->fields->catalog);
234
free(drizzle->fields->db);
235
free(drizzle->fields->table);
236
free(drizzle->fields->org_table);
237
free(drizzle->fields->name);
238
free(drizzle->fields->org_name);
239
free(drizzle->fields->def);
240
free(drizzle->fields);
243
/* init_alloc_root(&drizzle->field_alloc,8192,0); */ /* Assume rowlength < 8192 */
245
drizzle->field_count= 0; /* For API */
246
drizzle->warning_count= 0;
256
drizzle_free_result(DRIZZLE_RES *result)
804
reset_sigpipe(mysql);
805
DBUG_PRINT("exit",("result: %d", result));
809
void free_old_query(MYSQL *mysql)
811
DBUG_ENTER("free_old_query");
813
free_root(&mysql->field_alloc,MYF(0));
814
init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */
816
mysql->field_count= 0; /* For API */
817
mysql->warning_count= 0;
823
Flush result set sent from server
826
static void cli_flush_use_result(MYSQL *mysql)
828
/* Clear the current execution status */
829
DBUG_ENTER("cli_flush_use_result");
830
DBUG_PRINT("warning",("Not all packets read, clearing them"));
834
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
836
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
838
if (protocol_41(mysql))
840
char *pos= (char*) mysql->net.read_pos + 1;
841
mysql->warning_count=uint2korr(pos); pos+=2;
842
mysql->server_status=uint2korr(pos); pos+=2;
844
break; /* End of data */
852
static my_bool is_NT(void)
854
char *os=getenv("OS");
855
return (os && !strcmp(os, "Windows_NT")) ? 1 : 0;
862
Check server side variable 'license'.
864
If the variable does not exist or does not contain 'Commercial',
865
we're talking to non-commercial server from commercial client.
868
@retval !0 network error or the server is not commercial.
869
Error code is saved in mysql->net.last_errno.
872
static int check_license(MYSQL *mysql)
876
NET *net= &mysql->net;
877
static const char query[]= "SELECT @@license";
878
static const char required_license[]= STRINGIFY_ARG(LICENSE);
880
if (mysql_real_query(mysql, query, sizeof(query)-1))
882
if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
884
set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
885
ER(CR_WRONG_LICENSE), required_license);
889
if (!(res= mysql_use_result(mysql)))
891
row= mysql_fetch_row(res);
893
If no rows in result set, or column value is NULL (none of these
894
two is ever true for server variables now), or column value
895
mismatch, set wrong license error.
897
if (!net->last_errno &&
899
strncmp(row[0], required_license, sizeof(required_license))))
901
set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
902
ER(CR_WRONG_LICENSE), required_license);
904
mysql_free_result(res);
905
return net->last_errno;
907
#endif /* CHECK_LICENSE */
910
/**************************************************************************
912
**************************************************************************/
914
void end_server(MYSQL *mysql)
916
int save_errno= errno;
917
DBUG_ENTER("end_server");
918
if (mysql->net.vio != 0)
920
init_sigpipe_variables
921
DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio)));
923
vio_delete(mysql->net.vio);
924
reset_sigpipe(mysql);
925
mysql->net.vio= 0; /* Marker */
927
net_end(&mysql->net);
928
free_old_query(mysql);
935
mysql_free_result(MYSQL_RES *result)
937
DBUG_ENTER("mysql_free_result");
938
DBUG_PRINT("enter",("mysql_res: 0x%lx", (long) result));
260
DRIZZLE *drizzle= result->handle;
941
MYSQL *mysql= result->handle;
263
if (drizzle->unbuffered_fetch_owner == &result->unbuffered_fetch_cancelled)
264
drizzle->unbuffered_fetch_owner= 0;
265
if (drizzle->status == DRIZZLE_STATUS_USE_RESULT)
944
if (mysql->unbuffered_fetch_owner == &result->unbuffered_fetch_cancelled)
945
mysql->unbuffered_fetch_owner= 0;
946
if (mysql->status == MYSQL_STATUS_USE_RESULT)
267
(*drizzle->methods->flush_use_result)(drizzle);
268
drizzle->status=DRIZZLE_STATUS_READY;
269
if (drizzle->unbuffered_fetch_owner)
270
*drizzle->unbuffered_fetch_owner= true;
948
(*mysql->methods->flush_use_result)(mysql);
949
mysql->status=MYSQL_STATUS_READY;
950
if (mysql->unbuffered_fetch_owner)
951
*mysql->unbuffered_fetch_owner= TRUE;
273
954
free_rows(result->data);
274
/* TODO: free result->fields */
956
free_root(&result->field_alloc,MYF(0));
276
free((unsigned char*) result->row);
277
free((unsigned char*) result);
958
my_free((uchar*) result->row,MYF(0));
959
my_free((uchar*) result,MYF(0));
964
/****************************************************************************
965
Get options from my.cnf
966
****************************************************************************/
968
static const char *default_options[]=
970
"port","socket","compress","password","pipe", "timeout", "user",
971
"init-command", "host", "database", "debug", "return-found-rows",
972
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
973
"character-sets-dir", "default-character-set", "interactive-timeout",
974
"connect-timeout", "local-infile", "disable-local-infile",
975
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
976
"multi-results", "multi-statements", "multi-queries", "secure-auth",
977
"report-data-truncation",
981
static TYPELIB option_types={array_elements(default_options)-1,
982
"options",default_options, NULL};
984
const char *sql_protocol_names_lib[] =
985
{ "TCP", "SOCKET", "PIPE", "MEMORY", NullS };
986
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
987
sql_protocol_names_lib, NULL};
989
static int add_init_command(struct st_mysql_options *options, const char *cmd)
993
if (!options->init_commands)
995
options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
997
init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
1000
if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
1001
insert_dynamic(options->init_commands, (uchar*)&tmp))
1003
my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
1010
void mysql_read_default_options(struct st_mysql_options *options,
1011
const char *filename,const char *group)
1014
char *argv_buff[1],**argv;
1015
const char *groups[3];
1016
DBUG_ENTER("mysql_read_default_options");
1017
DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL"));
1019
argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
1020
groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
1022
load_defaults(filename, groups, &argc, &argv);
1023
if (argc != 1) /* If some default option */
1028
/* DBUG_PRINT("info",("option: %s",option[0])); */
1029
if (option[0][0] == '-' && option[0][1] == '-')
1031
char *end=strcend(*option,'=');
1036
*end=0; /* Remove '=' */
1038
/* Change all '_' in variable name to '-' */
1039
for (end= *option ; *(end= strcend(end,'_')) ; )
1041
switch (find_type(*option+2,&option_types,2)) {
1044
options->port=atoi(opt_arg);
1046
case 2: /* socket */
1049
my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
1050
options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
1053
case 3: /* compress */
1054
options->compress=1;
1055
options->client_flag|= CLIENT_COMPRESS;
1057
case 4: /* password */
1060
my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
1061
options->password=my_strdup(opt_arg,MYF(MY_WME));
1065
options->protocol = MYSQL_PROTOCOL_PIPE;
1066
case 20: /* connect_timeout */
1067
case 6: /* timeout */
1069
options->connect_timeout=atoi(opt_arg);
1074
my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
1075
options->user=my_strdup(opt_arg,MYF(MY_WME));
1078
case 8: /* init-command */
1079
add_init_command(options,opt_arg);
1084
my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
1085
options->host=my_strdup(opt_arg,MYF(MY_WME));
1088
case 10: /* database */
1091
my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
1092
options->db=my_strdup(opt_arg,MYF(MY_WME));
1095
case 11: /* debug */
1097
mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace");
1100
case 12: /* return-found-rows */
1101
options->client_flag|=CLIENT_FOUND_ROWS;
1103
case 13: /* Ignore SSL options */
1109
case 17: /* charset-lib */
1110
my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
1111
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
1114
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
1115
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
1117
case 19: /* Interactive-timeout */
1118
options->client_flag|= CLIENT_INTERACTIVE;
1121
if (!opt_arg || atoi(opt_arg) != 0)
1122
options->client_flag|= CLIENT_LOCAL_FILES;
1124
options->client_flag&= ~CLIENT_LOCAL_FILES;
1127
options->client_flag&= ~CLIENT_LOCAL_FILES;
1129
case 24: /* max-allowed-packet */
1131
options->max_allowed_packet= atoi(opt_arg);
1133
case 25: /* protocol */
1134
if ((options->protocol= find_type(opt_arg,
1135
&sql_protocol_typelib,0)) <= 0)
1137
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
1141
case 26: /* shared_memory_base_name */
1143
if (options->shared_memory_base_name != def_shared_memory_base_name)
1144
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
1145
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
1148
case 27: /* multi-results */
1149
options->client_flag|= CLIENT_MULTI_RESULTS;
1151
case 28: /* multi-statements */
1152
case 29: /* multi-queries */
1153
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
1155
case 30: /* secure-auth */
1156
options->secure_auth= TRUE;
1158
case 31: /* report-data-truncation */
1159
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
1162
DBUG_PRINT("warning",("unknown option: %s",option[0]));
1167
free_defaults(argv);
1172
/**************************************************************************
1173
Get column lengths of the current row
1174
If one uses mysql_use_result, res->lengths contains the length information,
1175
else the lengths are calculated from the offset between pointers.
1176
**************************************************************************/
1178
static void cli_fetch_lengths(ulong *to, MYSQL_ROW column,
1179
unsigned int field_count)
1185
prev_length=0; /* Keep gcc happy */
1186
for (end=column + field_count + 1 ; column != end ; column++, to++)
1193
if (start) /* Found end of prev string */
1194
*prev_length= (ulong) (*column-start-1);
1200
/***************************************************************************
1201
Change field rows to field structs
1202
***************************************************************************/
1205
unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
1206
my_bool default_value, uint server_capabilities)
1209
MYSQL_FIELD *field,*result;
1210
ulong lengths[9]; /* Max of fields */
1211
DBUG_ENTER("unpack_fields");
1213
field= result= (MYSQL_FIELD*) alloc_root(alloc,
1214
(uint) sizeof(*field)*fields);
1217
free_rows(data); /* Free old data */
1220
bzero((char*) field, (uint) sizeof(MYSQL_FIELD)*fields);
1221
if (server_capabilities & CLIENT_PROTOCOL_41)
1223
/* server is 4.1, and returns the new field result format */
1224
for (row=data->data; row ; row = row->next,field++)
1227
/* fields count may be wrong */
1228
DBUG_ASSERT((uint) (field - result) < fields);
1229
cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
1230
field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]);
1231
field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]);
1232
field->table= strmake_root(alloc,(char*) row->data[2], lengths[2]);
1233
field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]);
1234
field->name= strmake_root(alloc,(char*) row->data[4], lengths[4]);
1235
field->org_name= strmake_root(alloc,(char*) row->data[5], lengths[5]);
1237
field->catalog_length= lengths[0];
1238
field->db_length= lengths[1];
1239
field->table_length= lengths[2];
1240
field->org_table_length= lengths[3];
1241
field->name_length= lengths[4];
1242
field->org_name_length= lengths[5];
1244
/* Unpack fixed length parts */
1245
pos= (uchar*) row->data[6];
1246
field->charsetnr= uint2korr(pos);
1247
field->length= (uint) uint4korr(pos+2);
1248
field->type= (enum enum_field_types) pos[6];
1249
field->flags= uint2korr(pos+7);
1250
field->decimals= (uint) pos[9];
1252
if (INTERNAL_NUM_FIELD(field))
1253
field->flags|= NUM_FLAG;
1254
if (default_value && row->data[7])
1256
field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]);
1257
field->def_length= lengths[7];
1261
field->max_length= 0;
1264
#ifndef DELETE_SUPPORT_OF_4_0_PROTOCOL
1267
/* old protocol, for backward compatibility */
1268
for (row=data->data; row ; row = row->next,field++)
1270
cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
1271
field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
1272
field->name= strdup_root(alloc,(char*) row->data[1]);
1273
field->length= (uint) uint3korr(row->data[2]);
1274
field->type= (enum enum_field_types) (uchar) row->data[3][0];
1276
field->catalog=(char*) "";
1277
field->db= (char*) "";
1278
field->catalog_length= 0;
1279
field->db_length= 0;
1280
field->org_table_length= field->table_length= lengths[0];
1281
field->name_length= lengths[1];
1283
if (server_capabilities & CLIENT_LONG_FLAG)
1285
field->flags= uint2korr(row->data[4]);
1286
field->decimals=(uint) (uchar) row->data[4][2];
1290
field->flags= (uint) (uchar) row->data[4][0];
1291
field->decimals=(uint) (uchar) row->data[4][1];
1293
if (INTERNAL_NUM_FIELD(field))
1294
field->flags|= NUM_FLAG;
1295
if (default_value && row->data[5])
1297
field->def=strdup_root(alloc,(char*) row->data[5]);
1298
field->def_length= lengths[5];
1302
field->max_length= 0;
1305
#endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */
1306
free_rows(data); /* Free old data */
1307
DBUG_RETURN(result);
284
1310
/* Read all rows (fields or data) from server */
286
DRIZZLE_DATA *cli_read_rows(DRIZZLE *drizzle, DRIZZLE_FIELD *DRIZZLE_FIELDs, uint32_t fields)
1312
MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
1313
unsigned int fields)
293
DRIZZLE_DATA *result;
294
DRIZZLE_ROWS **prev_ptr,*cur;
295
NET *net = &drizzle->net;
1321
MYSQL_ROWS **prev_ptr,*cur;
1322
NET *net = &mysql->net;
1323
DBUG_ENTER("cli_read_rows");
297
if ((pkt_len= cli_safe_read(drizzle)) == packet_error)
299
if (!(result=(DRIZZLE_DATA*) malloc(sizeof(DRIZZLE_DATA))))
1325
if ((pkt_len= cli_safe_read(mysql)) == packet_error)
1327
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
1328
MYF(MY_WME | MY_ZEROFILL))))
301
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY,
302
sqlstate_get_unknown());
1330
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
305
memset(result, 0, sizeof(DRIZZLE_DATA));
1333
init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
1334
result->alloc.min_malloc=sizeof(MYSQL_ROWS);
306
1335
prev_ptr= &result->data;
308
1337
result->fields=fields;
311
The last EOF packet is either a 254 (0xFE) character followed by 1-7 status bytes.
1340
The last EOF packet is either a single 254 character or (in MySQL 4.1)
1341
254 followed by 1-7 status bytes.
313
1343
This doesn't conflict with normal usage of 254 which stands for a
314
1344
string where the length of the string is 8 bytes. (see net_field_length())
317
while (*(cp=net->read_pos) != DRIZZLE_PROTOCOL_NO_MORE_DATA || pkt_len >= 8)
1347
while (*(cp=net->read_pos) != 254 || pkt_len >= 8)
320
if (!(cur= (DRIZZLE_ROWS*) malloc(sizeof(DRIZZLE_ROWS))) ||
321
!(cur->data= ((DRIZZLE_ROW) malloc((fields+1)*sizeof(char *)+pkt_len))))
1350
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
1351
sizeof(MYSQL_ROWS))) ||
1352
!(cur->data= ((MYSQL_ROW)
1353
alloc_root(&result->alloc,
1354
(fields+1)*sizeof(char *)+pkt_len))))
323
1356
free_rows(result);
324
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
1357
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
328
1361
prev_ptr= &cur->next;
422
*prev_pos=0; /* Terminate prev field */
1455
*prev_pos=0; /* Terminate prev field */
425
row[field]=(char*) prev_pos+1; /* End of last field */
426
*prev_pos=0; /* Terminate last field */
1458
row[field]=(char*) prev_pos+1; /* End of last field */
1459
*prev_pos=0; /* Terminate last field */
1464
/****************************************************************************
1465
Init MySQL structure or allocate one
1466
****************************************************************************/
1469
mysql_init(MYSQL *mysql)
1471
if (mysql_server_init(0, NULL, NULL))
1475
if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
1477
set_mysql_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
1483
bzero((char*) (mysql), sizeof(*(mysql)));
1484
mysql->options.connect_timeout= CONNECT_TIMEOUT;
1485
mysql->charset=default_client_charset_info;
1486
strmov(mysql->net.sqlstate, not_error_sqlstate);
1489
Only enable LOAD DATA INFILE by default if configured with
1490
--enable-local-infile
1493
#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER)
1494
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
1498
mysql->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
1501
mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION;
1502
mysql->options.report_data_truncation= TRUE; /* default */
1505
By default we don't reconnect because it could silently corrupt data (after
1506
reconnection you potentially lose table locks, user variables, session
1507
variables (transactions but they are specifically dealt with in
1509
This is a change: < 5.0.3 mysql->reconnect was set to 1 by default.
1510
How this change impacts existing apps:
1511
- existing apps which relyed on the default will see a behaviour change;
1512
they will have to set reconnect=1 after mysql_real_connect().
1513
- existing apps which explicitely asked for reconnection (the only way they
1514
could do it was by setting mysql.reconnect to 1 after mysql_real_connect())
1515
will not see a behaviour change.
1516
- existing apps which explicitely asked for no reconnection
1517
(mysql.reconnect=0) will not see a behaviour change.
1519
mysql->reconnect= 0;
1526
Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
1527
NB! Errors are not reported until you do mysql_real_connect.
1530
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
1533
mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
1534
const char *key __attribute__((unused)),
1535
const char *cert __attribute__((unused)),
1536
const char *ca __attribute__((unused)),
1537
const char *capath __attribute__((unused)),
1538
const char *cipher __attribute__((unused)))
1540
DBUG_ENTER("mysql_ssl_set");
1546
Free strings in the SSL structure and clear 'use_ssl' flag.
1547
NB! Errors are not reported until you do mysql_real_connect.
1551
Return the SSL cipher (if any) used for current
1552
connection to the server.
1555
mysql_get_ssl_cipher()
1556
mysql pointer to the mysql connection
1560
const char * STDCALL
1561
mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused)))
1563
DBUG_ENTER("mysql_get_ssl_cipher");
1569
Check the server's (subject) Common Name against the
1570
hostname we connected to
1573
ssl_verify_server_cert()
1574
vio pointer to a SSL connected vio
1575
server_hostname name of the server that we connected to
1579
1 Failed to validate server
1585
Note that the mysql argument must be initialized with mysql_init()
1586
before calling mysql_real_connect !
1589
static my_bool cli_read_query_result(MYSQL *mysql);
1590
static MYSQL_RES *cli_use_result(MYSQL *mysql);
1592
static MYSQL_METHODS client_methods=
1594
cli_read_query_result, /* read_query_result */
1595
cli_advanced_command, /* advanced_command */
1596
cli_read_rows, /* read_rows */
1597
cli_use_result, /* use_result */
1598
cli_fetch_lengths, /* fetch_lengths */
1599
cli_flush_use_result, /* flush_use_result */
1600
#ifndef MYSQL_SERVER
1601
cli_list_fields, /* list_fields */
1602
cli_unbuffered_fetch, /* unbuffered_fetch */
1603
cli_read_statistics, /* read_statistics */
1604
cli_read_query_result, /* next_result */
1605
cli_read_change_user_result, /* read_change_user_result */
1610
int mysql_init_character_set(MYSQL *mysql)
1612
const char *default_collation_name;
1614
/* Set character set */
1615
if (!mysql->options.charset_name)
1617
default_collation_name= MYSQL_DEFAULT_COLLATION_NAME;
1618
if (!(mysql->options.charset_name=
1619
my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
1623
default_collation_name= NULL;
1626
const char *save= charsets_dir;
1627
if (mysql->options.charset_dir)
1628
charsets_dir=mysql->options.charset_dir;
1629
mysql->charset=get_charset_by_csname(mysql->options.charset_name,
1630
MY_CS_PRIMARY, MYF(MY_WME));
1631
if (mysql->charset && default_collation_name)
1633
CHARSET_INFO *collation;
1635
get_charset_by_name(default_collation_name, MYF(MY_WME))))
1637
if (!my_charset_same(mysql->charset, collation))
1639
my_printf_error(ER_UNKNOWN_ERROR,
1640
"COLLATION %s is not valid for CHARACTER SET %s",
1642
default_collation_name, mysql->options.charset_name);
1643
mysql->charset= NULL;
1647
mysql->charset= collation;
1651
mysql->charset= NULL;
1656
if (!mysql->charset)
1658
if (mysql->options.charset_dir)
1659
set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
1660
ER(CR_CANT_READ_CHARSET),
1661
mysql->options.charset_name,
1662
mysql->options.charset_dir);
1665
char cs_dir_name[FN_REFLEN];
1666
get_charsets_dir(cs_dir_name);
1667
set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
1668
ER(CR_CANT_READ_CHARSET),
1669
mysql->options.charset_name,
1680
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
1681
const char *passwd, const char *db,
1682
uint port, const char *unix_socket,ulong client_flag)
1684
char buff[NAME_LEN+USERNAME_LENGTH+100];
1685
char *end,*host_info;
1687
NET *net= &mysql->net;
1689
thr_alarm_t alarmed;
1693
HANDLE hPipe=INVALID_HANDLE_VALUE;
1695
#ifdef HAVE_SYS_UN_H
1696
struct sockaddr_un UNIXaddr;
1698
init_sigpipe_variables
1699
DBUG_ENTER("mysql_real_connect");
1701
DBUG_PRINT("enter",("host: %s db: %s user: %s",
1702
host ? host : "(Null)",
1704
user ? user : "(Null)"));
1706
/* Don't give sigpipe errors if the client doesn't want them */
1708
mysql->methods= &client_methods;
1709
net->vio = 0; /* If something goes wrong */
1710
mysql->client_flag=0; /* For handshake */
1712
/* use default options */
1713
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
1715
mysql_read_default_options(&mysql->options,
1716
(mysql->options.my_cnf_file ?
1717
mysql->options.my_cnf_file : "my"),
1718
mysql->options.my_cnf_group);
1719
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1720
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1721
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
1724
/* Some empty-string-tests are done because of ODBC */
1725
if (!host || !host[0])
1726
host=mysql->options.host;
1727
if (!user || !user[0])
1729
user=mysql->options.user;
1735
passwd=mysql->options.password;
1736
#if !defined(DONT_USE_MYSQL_PWD) && !defined(MYSQL_SERVER)
1738
passwd=getenv("MYSQL_PWD"); /* get it from environment */
1744
db=mysql->options.db;
1746
port=mysql->options.port;
1748
unix_socket=mysql->options.unix_socket;
1750
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
1753
Part 0: Grab a socket and connect it to the server
1755
#if defined(HAVE_SMEM)
1756
if ((!mysql->options.protocol ||
1757
mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) &&
1758
(!host || !strcmp(host,LOCAL_HOST)))
1760
if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) ==
1761
INVALID_HANDLE_VALUE)
1764
("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
1765
host ? host : "<null>",
1766
unix_socket ? unix_socket : "<null>",
1767
(int) mysql->options.shared_memory_base_name,
1769
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
1773
Try also with PIPE or TCP/IP. Clear the error from
1774
create_shared_memory().
1777
net_clear_error(net);
1781
mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
1783
host=mysql->options.shared_memory_base_name;
1784
my_snprintf(host_info=buff, sizeof(buff)-1,
1785
ER(CR_SHARED_MEMORY_CONNECTION), host);
1788
#endif /* HAVE_SMEM */
1789
#if defined(HAVE_SYS_UN_H)
1791
(!mysql->options.protocol ||
1792
mysql->options.protocol == MYSQL_PROTOCOL_SOCKET) &&
1793
(unix_socket || mysql_unix_port) &&
1794
(!host || !strcmp(host,LOCAL_HOST)))
1796
my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
1797
if (sock == SOCKET_ERROR)
1799
set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR,
1801
ER(CR_SOCKET_CREATE_ERROR),
1806
net->vio= vio_new(sock, VIO_TYPE_SOCKET,
1807
VIO_LOCALHOST | VIO_BUFFERED_READ);
1810
DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
1811
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1818
unix_socket= mysql_unix_port;
1819
host_info= (char*) ER(CR_LOCALHOST_CONNECTION);
1820
DBUG_PRINT("info", ("Using UNIX sock '%s'", unix_socket));
1822
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
1823
UNIXaddr.sun_family= AF_UNIX;
1824
strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);
1826
if (my_connect(sock, (struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
1827
mysql->options.connect_timeout))
1829
DBUG_PRINT("error",("Got error %d on connect to local server",
1831
set_mysql_extended_error(mysql, CR_CONNECTION_ERROR,
1833
ER(CR_CONNECTION_ERROR),
1834
unix_socket, socket_errno);
1835
vio_delete(net->vio);
1839
mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
1841
#elif defined(__WIN__)
1843
(mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1844
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1845
(! have_tcpip && (unix_socket || !host && is_NT()))))
1847
if ((hPipe= create_named_pipe(mysql, mysql->options.connect_timeout,
1848
(char**) &host, (char**) &unix_socket)) ==
1849
INVALID_HANDLE_VALUE)
1852
("host: '%s' socket: '%s' have_tcpip: %d",
1853
host ? host : "<null>",
1854
unix_socket ? unix_socket : "<null>",
1856
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1857
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1858
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
1860
/* Try also with TCP/IP */
1864
net->vio=vio_new_win32pipe(hPipe);
1865
my_snprintf(host_info=buff, sizeof(buff)-1,
1866
ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
1871
(!mysql->options.protocol ||
1872
mysql->options.protocol == MYSQL_PROTOCOL_TCP))
1874
struct addrinfo *res_lst, hints, *t_res;
1876
char port_buf[NI_MAXSERV];
1878
unix_socket=0; /* This is not used */
1886
my_snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
1887
DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host, port));
1889
thr_alarm_init(&alarmed);
1890
thr_alarm(&alarmed, mysql->options.connect_timeout, &alarm_buff);
1893
DBUG_PRINT("info",("IP '%s'", "client"));
1896
thr_end_alarm(&alarmed);
1899
memset(&hints, 0, sizeof(hints));
1900
hints.ai_socktype= SOCK_STREAM;
1901
hints.ai_protocol= IPPROTO_TCP;
1902
hints.ai_family= AF_UNSPEC;
1904
DBUG_PRINT("info",("IPV6 getaddrinfo %s", host));
1905
my_snprintf(port_buf, NI_MAXSERV, "%d", port);
1906
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
1911
For DBUG we are keeping the right message but for client we default to
1912
historical error message.
1914
DBUG_PRINT("info",("IPV6 getaddrinfo error %d", gai_errno));
1915
set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
1916
ER(CR_UNKNOWN_HOST), host, errno);
1921
/* We only look at the first item (something to think about changing in the future) */
1924
my_socket sock= socket(t_res->ai_family, t_res->ai_socktype,
1925
t_res->ai_protocol);
1926
if (sock == SOCKET_ERROR)
1928
set_mysql_extended_error(mysql, CR_IPSOCK_ERROR, unknown_sqlstate,
1929
ER(CR_IPSOCK_ERROR), socket_errno);
1930
freeaddrinfo(res_lst);
1934
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
1937
DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
1938
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1940
freeaddrinfo(res_lst);
1944
if (my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
1945
mysql->options.connect_timeout))
1947
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,
1949
set_mysql_extended_error(mysql, CR_CONN_HOST_ERROR, unknown_sqlstate,
1950
ER(CR_CONN_HOST_ERROR), host, socket_errno);
1951
vio_delete(net->vio);
1953
freeaddrinfo(res_lst);
1958
freeaddrinfo(res_lst);
1963
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
1964
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1968
if (my_net_init(net, net->vio))
1970
vio_delete(net->vio);
1972
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1975
vio_keepalive(net->vio,TRUE);
1977
/* If user set read_timeout, let it override the default */
1978
if (mysql->options.read_timeout)
1979
my_net_set_read_timeout(net, mysql->options.read_timeout);
1981
/* If user set write_timeout, let it override the default */
1982
if (mysql->options.write_timeout)
1983
my_net_set_write_timeout(net, mysql->options.write_timeout);
1985
if (mysql->options.max_allowed_packet)
1986
net->max_packet_size= mysql->options.max_allowed_packet;
1988
/* Get version info */
1989
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
1990
if (mysql->options.connect_timeout &&
1991
vio_poll_read(net->vio, mysql->options.connect_timeout))
1993
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
1994
ER(CR_SERVER_LOST_EXTENDED),
1995
"waiting for initial communication packet",
2001
Part 1: Connection established, read and parse first packet
2004
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
2006
if (mysql->net.last_errno == CR_SERVER_LOST)
2007
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2008
ER(CR_SERVER_LOST_EXTENDED),
2009
"reading initial communication packet",
2013
/* Check if version of protocol matches current one */
2015
mysql->protocol_version= net->read_pos[0];
2016
DBUG_DUMP("packet",(uchar*) net->read_pos,10);
2017
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
2018
PROTOCOL_VERSION, mysql->protocol_version));
2019
if (mysql->protocol_version != PROTOCOL_VERSION)
2021
set_mysql_extended_error(mysql, CR_VERSION_ERROR, unknown_sqlstate,
2022
ER(CR_VERSION_ERROR), mysql->protocol_version,
2026
end=strend((char*) net->read_pos+1);
2027
mysql->thread_id=uint4korr(end+1);
2030
Scramble is split into two parts because old clients does not understand
2031
long scrambles; here goes the first part.
2033
strmake(mysql->scramble, end, SCRAMBLE_LENGTH_323);
2034
end+= SCRAMBLE_LENGTH_323+1;
2036
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
2037
mysql->server_capabilities=uint2korr(end);
2038
if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
2040
/* New protocol with 16 bytes to describe server characteristics */
2041
mysql->server_language=end[2];
2042
mysql->server_status=uint2korr(end+3);
2045
if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
2046
(char *) net->read_pos))
2047
strmake(mysql->scramble+SCRAMBLE_LENGTH_323, end,
2048
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
2050
mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
2052
if (mysql->options.secure_auth && passwd[0] &&
2053
!(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
2055
set_mysql_error(mysql, CR_SECURE_AUTH, unknown_sqlstate);
2059
if (mysql_init_character_set(mysql))
2062
/* Save connection information */
2063
if (!my_multi_malloc(MYF(0),
2064
&mysql->host_info, (uint) strlen(host_info)+1,
2065
&mysql->host, (uint) strlen(host)+1,
2066
&mysql->unix_socket,unix_socket ?
2067
(uint) strlen(unix_socket)+1 : (uint) 1,
2068
&mysql->server_version,
2069
(uint) (end - (char*) net->read_pos),
2071
!(mysql->user=my_strdup(user,MYF(0))) ||
2072
!(mysql->passwd=my_strdup(passwd,MYF(0))))
2074
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
2077
strmov(mysql->host_info,host_info);
2078
strmov(mysql->host,host);
2080
strmov(mysql->unix_socket,unix_socket);
2082
mysql->unix_socket=0;
2083
strmov(mysql->server_version,(char*) net->read_pos+1);
2087
Part 2: format and send client info to the server for access check
2090
client_flag|=mysql->options.client_flag;
2091
client_flag|=CLIENT_CAPABILITIES;
2092
if (client_flag & CLIENT_MULTI_STATEMENTS)
2093
client_flag|= CLIENT_MULTI_RESULTS;
2096
client_flag|=CLIENT_CONNECT_WITH_DB;
2098
/* Remove options that server doesn't support */
2099
client_flag= ((client_flag &
2100
~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
2101
(client_flag & mysql->server_capabilities));
2102
client_flag&= ~CLIENT_COMPRESS;
2104
if (client_flag & CLIENT_PROTOCOL_41)
2106
/* 4.1 server and 4.1 client has a 32 byte option flag */
2107
int4store(buff,client_flag);
2108
int4store(buff+4, net->max_packet_size);
2109
buff[8]= (char) mysql->charset->number;
2110
bzero(buff+9, 32-9);
2115
int2store(buff,client_flag);
2116
int3store(buff+2,net->max_packet_size);
2119
mysql->client_flag=client_flag;
2121
DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
2122
mysql->server_version,mysql->server_capabilities,
2123
mysql->server_status, client_flag));
2124
/* This needs to be changed as it's not useful with big packets */
2125
if (user && user[0])
2126
strmake(end,user,USERNAME_LENGTH); /* Max user name */
2128
read_user_name((char*) end);
2130
/* We have to handle different version of handshake here */
2131
#ifdef _CUSTOMCONFIG_
2132
#include "_cust_libmysql.h"
2134
DBUG_PRINT("info",("user: %s",end));
2135
end= strend(end) + 1;
2138
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2140
*end++= SCRAMBLE_LENGTH;
2141
scramble(end, mysql->scramble, passwd);
2142
end+= SCRAMBLE_LENGTH;
2146
scramble_323(end, mysql->scramble, passwd);
2147
end+= SCRAMBLE_LENGTH_323 + 1;
2151
*end++= '\0'; /* empty password */
2153
/* Add database if needed */
2154
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
2156
end= strmake(end, db, NAME_LEN) + 1;
2157
mysql->db= my_strdup(db,MYF(MY_WME));
2160
/* Write authentication package */
2161
if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
2163
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2164
ER(CR_SERVER_LOST_EXTENDED),
2165
"sending authentication information",
2171
Part 3: Authorization data's been sent. Now server can reply with
2172
OK-packet, or re-request scrambled password.
2175
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
2177
if (mysql->net.last_errno == CR_SERVER_LOST)
2178
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2179
ER(CR_SERVER_LOST_EXTENDED),
2180
"reading authorization packet",
2185
if (pkt_length == 1 && net->read_pos[0] == 254 &&
2186
mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2189
By sending this very specific reply server asks us to send scrambled
2190
password in old format.
2192
scramble_323(buff, mysql->scramble, passwd);
2193
if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
2196
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2197
ER(CR_SERVER_LOST_EXTENDED),
2198
"sending password information",
2202
/* Read what server thinks about out new auth message report */
2203
if (cli_safe_read(mysql) == packet_error)
2205
if (mysql->net.last_errno == CR_SERVER_LOST)
2206
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2207
ER(CR_SERVER_LOST_EXTENDED),
2208
"reading final connect information",
2214
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
2217
#ifdef CHECK_LICENSE
2218
if (check_license(mysql))
2222
if (db && mysql_select_db(mysql, db))
2224
if (mysql->net.last_errno == CR_SERVER_LOST)
2225
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2226
ER(CR_SERVER_LOST_EXTENDED),
2227
"Setting intital database",
2232
if (mysql->options.init_commands)
2234
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
2235
char **ptr= (char**)init_commands->buffer;
2236
char **end_command= ptr + init_commands->elements;
2238
my_bool reconnect=mysql->reconnect;
2241
for (; ptr < end_command; ptr++)
2244
if (mysql_real_query(mysql,*ptr, (ulong) strlen(*ptr)))
2248
if (!(res= cli_use_result(mysql)))
2250
mysql_free_result(res);
2253
mysql->reconnect=reconnect;
2256
DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
2257
reset_sigpipe(mysql);
2261
reset_sigpipe(mysql);
2262
DBUG_PRINT("error",("message: %u/%s (%s)",
2267
/* Free alloced memory */
2269
mysql_close_free(mysql);
2270
if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
2271
mysql_close_free_options(mysql);
2277
my_bool mysql_reconnect(MYSQL *mysql)
2280
DBUG_ENTER("mysql_reconnect");
2282
DBUG_PRINT("enter", ("mysql->reconnect: %d", mysql->reconnect));
2284
if (!mysql->reconnect ||
2285
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
2287
/* Allow reconnect next time */
2288
mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
2289
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
2292
mysql_init(&tmp_mysql);
2293
tmp_mysql.options= mysql->options;
2294
tmp_mysql.options.my_cnf_file= tmp_mysql.options.my_cnf_group= 0;
2296
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
2297
mysql->db, mysql->port, mysql->unix_socket,
2298
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
2300
mysql->net.last_errno= tmp_mysql.net.last_errno;
2301
strmov(mysql->net.last_error, tmp_mysql.net.last_error);
2302
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
2305
if (mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
2307
DBUG_PRINT("error", ("mysql_set_character_set() failed"));
2308
bzero((char*) &tmp_mysql.options,sizeof(tmp_mysql.options));
2309
mysql_close(&tmp_mysql);
2310
mysql->net.last_errno= tmp_mysql.net.last_errno;
2311
strmov(mysql->net.last_error, tmp_mysql.net.last_error);
2312
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
2316
DBUG_PRINT("info", ("reconnect succeded"));
2317
tmp_mysql.reconnect= 1;
2318
tmp_mysql.free_me= mysql->free_me;
2320
/* Don't free options as these are now used in tmp_mysql */
2321
bzero((char*) &mysql->options,sizeof(mysql->options));
2325
net_clear(&mysql->net, 1);
2326
mysql->affected_rows= ~(my_ulonglong) 0;
2331
/**************************************************************************
2332
Set current database
2333
**************************************************************************/
2336
mysql_select_db(MYSQL *mysql, const char *db)
2339
DBUG_ENTER("mysql_select_db");
2340
DBUG_PRINT("enter",("db: '%s'",db));
2342
if ((error=simple_command(mysql,COM_INIT_DB, (const uchar*) db,
2343
(ulong) strlen(db),0)))
2345
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
2346
mysql->db=my_strdup(db,MYF(MY_WME));
2351
/*************************************************************************
2352
Send a QUIT to the server and close the connection
2353
If handle is alloced by mysql connect free it.
2354
*************************************************************************/
2356
static void mysql_close_free_options(MYSQL *mysql)
2358
DBUG_ENTER("mysql_close_free_options");
2360
my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR));
2361
my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR));
2362
my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR));
2363
my_free(mysql->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
2364
my_free(mysql->options.db,MYF(MY_ALLOW_ZERO_PTR));
2365
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
2366
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
2367
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
2368
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
2369
my_free(mysql->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
2370
if (mysql->options.init_commands)
2372
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
2373
char **ptr= (char**)init_commands->buffer;
2374
char **end= ptr + init_commands->elements;
2375
for (; ptr<end; ptr++)
2376
my_free(*ptr,MYF(MY_WME));
2377
delete_dynamic(init_commands);
2378
my_free((char*)init_commands,MYF(MY_WME));
2381
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
2382
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
2383
#endif /* HAVE_SMEM */
2384
bzero((char*) &mysql->options,sizeof(mysql->options));
2389
static void mysql_close_free(MYSQL *mysql)
2391
my_free((uchar*) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR));
2392
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
2393
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
2394
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
2395
my_free(mysql->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
2396
mysql->info_buffer= 0;
2398
/* Clear pointers for better safety */
2399
mysql->host_info= mysql->user= mysql->passwd= mysql->db= 0;
2403
void STDCALL mysql_close(MYSQL *mysql)
2405
DBUG_ENTER("mysql_close");
2406
if (mysql) /* Some simple safety */
2408
/* If connection is still up, send a QUIT message */
2409
if (mysql->net.vio != 0)
2411
free_old_query(mysql);
2412
mysql->status=MYSQL_STATUS_READY; /* Force command */
2414
simple_command(mysql,COM_QUIT,(uchar*) 0,0,1);
2415
end_server(mysql); /* Sets mysql->net.vio= 0 */
2417
mysql_close_free_options(mysql);
2418
mysql_close_free(mysql);
2420
my_free((uchar*) mysql,MYF(0));
2426
static my_bool cli_read_query_result(MYSQL *mysql)
2432
DBUG_ENTER("cli_read_query_result");
2434
if ((length = cli_safe_read(mysql)) == packet_error)
2436
free_old_query(mysql); /* Free old result */
2437
#ifdef MYSQL_CLIENT /* Avoid warn of unused labels*/
2440
pos=(uchar*) mysql->net.read_pos;
2441
if ((field_count= net_field_length(&pos)) == 0)
2443
mysql->affected_rows= net_field_length_ll(&pos);
2444
mysql->insert_id= net_field_length_ll(&pos);
2445
DBUG_PRINT("info",("affected_rows: %lu insert_id: %lu",
2446
(ulong) mysql->affected_rows,
2447
(ulong) mysql->insert_id));
2448
if (protocol_41(mysql))
2450
mysql->server_status=uint2korr(pos); pos+=2;
2451
mysql->warning_count=uint2korr(pos); pos+=2;
2453
else if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
2455
/* MySQL 4.0 protocol */
2456
mysql->server_status=uint2korr(pos); pos+=2;
2457
mysql->warning_count= 0;
2459
DBUG_PRINT("info",("status: %u warning_count: %u",
2460
mysql->server_status, mysql->warning_count));
2461
if (pos < mysql->net.read_pos+length && net_field_length(&pos))
2462
mysql->info=(char*) pos;
2466
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
2470
if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES))
2472
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
2476
error= handle_local_infile(mysql,(char*) pos);
2477
if ((length= cli_safe_read(mysql)) == packet_error || error)
2479
goto get_info; /* Get info packet */
2482
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
2483
mysql->server_status|= SERVER_STATUS_IN_TRANS;
2485
if (!(fields=cli_read_rows(mysql,(MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5)))
2487
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
2488
(uint) field_count,0,
2489
mysql->server_capabilities)))
2491
mysql->status= MYSQL_STATUS_GET_RESULT;
2492
mysql->field_count= (uint) field_count;
2493
DBUG_PRINT("exit",("ok"));
2499
Send the query and return so we can do something else.
2500
Needs to be followed by mysql_read_query_result() when we want to
2501
finish processing it.
2505
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
2507
DBUG_ENTER("mysql_send_query");
2508
DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1));
2513
mysql_real_query(MYSQL *mysql, const char *query, ulong length)
2515
DBUG_ENTER("mysql_real_query");
2516
DBUG_PRINT("enter",("handle: 0x%lx", (long) mysql));
2517
DBUG_PRINT("query",("Query = '%-.4096s'",query));
2519
if (mysql_send_query(mysql,query,length))
2521
DBUG_RETURN((int) (*mysql->methods->read_query_result)(mysql));
2525
/**************************************************************************
2526
Alloc result struct for buffered results. All rows are read to buffer.
2527
mysql_data_seek may be used.
2528
**************************************************************************/
2530
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
2533
DBUG_ENTER("mysql_store_result");
2537
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2539
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2542
mysql->status=MYSQL_STATUS_READY; /* server is ready */
2543
if (!(result=(MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+
2545
mysql->field_count),
2546
MYF(MY_WME | MY_ZEROFILL))))
2548
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
2551
result->methods= mysql->methods;
2552
result->eof=1; /* Marker for buffered */
2553
result->lengths=(ulong*) (result+1);
2555
(*mysql->methods->read_rows)(mysql,mysql->fields,mysql->field_count)))
2557
my_free((uchar*) result,MYF(0));
2560
mysql->affected_rows= result->row_count= result->data->rows;
2561
result->data_cursor= result->data->data;
2562
result->fields= mysql->fields;
2563
result->field_alloc= mysql->field_alloc;
2564
result->field_count= mysql->field_count;
2565
/* The rest of result members is bzeroed in malloc */
2566
mysql->fields=0; /* fields is now in result */
2567
clear_alloc_root(&mysql->field_alloc);
2568
/* just in case this was mistakenly called after mysql_stmt_execute() */
2569
mysql->unbuffered_fetch_owner= 0;
2570
DBUG_RETURN(result); /* Data fetched */
2574
/**************************************************************************
2575
Alloc struct for use with unbuffered reads. Data is fetched by domand
2576
when calling to mysql_fetch_row.
2577
mysql_data_seek is a noop.
2579
No other queries may be specified with the same MYSQL handle.
2580
There shouldn't be much processing per row because mysql server shouldn't
2581
have to wait for the client (and will not wait more than 30 sec/packet).
2582
**************************************************************************/
2584
static MYSQL_RES * cli_use_result(MYSQL *mysql)
2587
DBUG_ENTER("cli_use_result");
2591
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2593
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2596
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
2597
sizeof(ulong)*mysql->field_count,
2598
MYF(MY_WME | MY_ZEROFILL))))
2600
result->lengths=(ulong*) (result+1);
2601
result->methods= mysql->methods;
2602
if (!(result->row=(MYSQL_ROW)
2603
my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME))))
2604
{ /* Ptrs: to one row */
2605
my_free((uchar*) result,MYF(0));
2608
result->fields= mysql->fields;
2609
result->field_alloc= mysql->field_alloc;
2610
result->field_count= mysql->field_count;
2611
result->current_field=0;
2612
result->handle= mysql;
2613
result->current_row= 0;
2614
mysql->fields=0; /* fields is now in result */
2615
clear_alloc_root(&mysql->field_alloc);
2616
mysql->status=MYSQL_STATUS_USE_RESULT;
2617
mysql->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
2618
DBUG_RETURN(result); /* Data is read to be fetched */
432
2623
Return next row of the query results
433
2624
**************************************************************************/
436
drizzle_fetch_row(DRIZZLE_RES *res)
2627
mysql_fetch_row(MYSQL_RES *res)
2629
DBUG_ENTER("mysql_fetch_row");
439
{ /* Unbufferred fetch */
2631
{ /* Unbufferred fetch */
442
DRIZZLE *drizzle= res->handle;
443
if (drizzle->status != DRIZZLE_STATUS_USE_RESULT)
445
drizzle_set_error(drizzle,
446
res->unbuffered_fetch_cancelled ?
447
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
448
sqlstate_get_unknown());
450
else if (!(read_one_row(drizzle, res->field_count, res->row, res->lengths)))
453
return(res->current_row=res->row);
2634
MYSQL *mysql= res->handle;
2635
if (mysql->status != MYSQL_STATUS_USE_RESULT)
2637
set_mysql_error(mysql,
2638
res->unbuffered_fetch_cancelled ?
2639
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
2642
else if (!(read_one_row(mysql, res->field_count, res->row, res->lengths)))
2645
DBUG_RETURN(res->current_row=res->row);
2647
DBUG_PRINT("info",("end of data"));
456
drizzle->status=DRIZZLE_STATUS_READY;
2649
mysql->status=MYSQL_STATUS_READY;
458
2651
Reset only if owner points to us: there is a chance that somebody
459
started new query after drizzle_stmt_close():
2652
started new query after mysql_stmt_close():
461
if (drizzle->unbuffered_fetch_owner == &res->unbuffered_fetch_cancelled)
462
drizzle->unbuffered_fetch_owner= 0;
463
/* Don't clear handle in drizzle_free_result */
2654
if (mysql->unbuffered_fetch_owner == &res->unbuffered_fetch_cancelled)
2655
mysql->unbuffered_fetch_owner= 0;
2656
/* Don't clear handle in mysql_free_result */
466
return((DRIZZLE_ROW) NULL);
2659
DBUG_RETURN((MYSQL_ROW) NULL);
470
2663
if (!res->data_cursor)
472
return(res->current_row=(DRIZZLE_ROW) NULL);
2665
DBUG_PRINT("info",("end of data"));
2666
DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
474
2668
tmp = res->data_cursor->data;
475
2669
res->data_cursor = res->data_cursor->next;
476
return(res->current_row=tmp);
2670
DBUG_RETURN(res->current_row=tmp);
481
2675
/**************************************************************************
482
2676
Get column lengths of the current row
483
If one uses drizzle_use_result, res->lengths contains the length information,
2677
If one uses mysql_use_result, res->lengths contains the length information,
484
2678
else the lengths are calculated from the offset between pointers.
485
2679
**************************************************************************/
488
drizzle_fetch_lengths(DRIZZLE_RES *res)
2682
mysql_fetch_lengths(MYSQL_RES *res)
492
2686
if (!(column=res->current_row))
493
return 0; /* Something is wrong */
2687
return 0; /* Something is wrong */
495
2689
(*res->methods->fetch_lengths)(res->lengths, column, res->field_count);
496
2690
return res->lengths;
501
drizzle_options(DRIZZLE *drizzle,enum drizzle_option option, const void *arg)
2695
mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
2697
DBUG_ENTER("mysql_option");
2698
DBUG_PRINT("enter",("option: %d",(int) option));
503
2699
switch (option) {
504
case DRIZZLE_OPT_CONNECT_TIMEOUT:
505
drizzle->options.connect_timeout= *(uint32_t*) arg;
507
case DRIZZLE_OPT_READ_TIMEOUT:
508
drizzle->options.read_timeout= *(uint32_t*) arg;
510
case DRIZZLE_OPT_WRITE_TIMEOUT:
511
drizzle->options.write_timeout= *(uint32_t*) arg;
513
case DRIZZLE_OPT_COMPRESS:
514
drizzle->options.compress= 1; /* Remember for connect */
515
drizzle->options.client_flag|= CLIENT_COMPRESS;
517
case DRIZZLE_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
518
if (!arg || (*(uint32_t*) arg) ? 1 : 0)
519
drizzle->options.client_flag|= CLIENT_LOCAL_FILES;
521
drizzle->options.client_flag&= ~CLIENT_LOCAL_FILES;
523
case DRIZZLE_READ_DEFAULT_FILE:
524
if (drizzle->options.my_cnf_file != NULL)
525
free(drizzle->options.my_cnf_file);
526
drizzle->options.my_cnf_file=strdup(arg);
528
case DRIZZLE_READ_DEFAULT_GROUP:
529
if (drizzle->options.my_cnf_group != NULL)
530
free(drizzle->options.my_cnf_group);
531
drizzle->options.my_cnf_group=strdup(arg);
533
case DRIZZLE_OPT_PROTOCOL:
535
case DRIZZLE_OPT_USE_REMOTE_CONNECTION:
536
case DRIZZLE_OPT_GUESS_CONNECTION:
537
drizzle->options.methods_to_use= option;
539
case DRIZZLE_SET_CLIENT_IP:
540
drizzle->options.client_ip= strdup(arg);
542
case DRIZZLE_SECURE_AUTH:
543
drizzle->options.secure_auth= *(const bool *) arg;
545
case DRIZZLE_REPORT_DATA_TRUNCATION:
546
drizzle->options.report_data_truncation= (*(const bool *) arg) ? 1 : 0;
548
case DRIZZLE_OPT_RECONNECT:
549
drizzle->reconnect= *(const bool *) arg;
551
case DRIZZLE_OPT_SSL_VERIFY_SERVER_CERT:
552
if (*(const bool*) arg)
553
drizzle->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
555
drizzle->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
2700
case MYSQL_OPT_CONNECT_TIMEOUT:
2701
mysql->options.connect_timeout= *(uint*) arg;
2703
case MYSQL_OPT_READ_TIMEOUT:
2704
mysql->options.read_timeout= *(uint*) arg;
2706
case MYSQL_OPT_WRITE_TIMEOUT:
2707
mysql->options.write_timeout= *(uint*) arg;
2709
case MYSQL_OPT_COMPRESS:
2710
mysql->options.compress= 1; /* Remember for connect */
2711
mysql->options.client_flag|= CLIENT_COMPRESS;
2713
case MYSQL_OPT_NAMED_PIPE: /* This option is depricated */
2714
mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */
2716
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
2717
if (!arg || test(*(uint*) arg))
2718
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
2720
mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
2722
case MYSQL_INIT_COMMAND:
2723
add_init_command(&mysql->options,arg);
2725
case MYSQL_READ_DEFAULT_FILE:
2726
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
2727
mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
2729
case MYSQL_READ_DEFAULT_GROUP:
2730
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
2731
mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
2733
case MYSQL_SET_CHARSET_DIR:
2734
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
2735
mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME));
2737
case MYSQL_SET_CHARSET_NAME:
2738
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
2739
mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
2741
case MYSQL_OPT_PROTOCOL:
2742
mysql->options.protocol= *(uint*) arg;
2744
case MYSQL_SHARED_MEMORY_BASE_NAME:
2746
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
2747
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
2748
mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
2751
case MYSQL_OPT_USE_REMOTE_CONNECTION:
2752
case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
2753
case MYSQL_OPT_GUESS_CONNECTION:
2754
mysql->options.methods_to_use= option;
2756
case MYSQL_SET_CLIENT_IP:
2757
mysql->options.client_ip= my_strdup(arg, MYF(MY_WME));
2759
case MYSQL_SECURE_AUTH:
2760
mysql->options.secure_auth= *(my_bool *) arg;
2762
case MYSQL_REPORT_DATA_TRUNCATION:
2763
mysql->options.report_data_truncation= test(*(my_bool *) arg);
2765
case MYSQL_OPT_RECONNECT:
2766
mysql->reconnect= *(my_bool *) arg;
2768
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
2769
if (*(my_bool*) arg)
2770
mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
2772
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
564
2781
/****************************************************************************
565
Functions to get information from the DRIZZLE structure
2782
Functions to get information from the MySQL structure
566
2783
These are functions to make shared libraries more usable.
567
2784
****************************************************************************/
570
uint64_t drizzle_num_rows(const DRIZZLE_RES *res)
2787
my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res)
572
2789
return res->row_count;
575
unsigned int drizzle_num_fields(const DRIZZLE_RES *res)
2792
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res)
577
2794
return res->field_count;
2797
uint STDCALL mysql_errno(MYSQL *mysql)
2799
return mysql ? mysql->net.last_errno : mysql_server_last_errno;
2803
const char * STDCALL mysql_error(MYSQL *mysql)
2805
return mysql ? mysql->net.last_error : mysql_server_last_error;
582
2810
Get version number for server in a form easy to test on
585
drizzle_get_server_version()
2813
mysql_get_server_version()
589
2817
4.1.0-alfa -> 40100
592
2820
We will ensure that a newer server always has a bigger number.