73
88
#include <sys/select.h>
79
96
#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);
99
#define CONNECT_TIMEOUT 20
101
#define CONNECT_TIMEOUT 0
104
#include "client_settings.h"
105
#include <sql_common.h>
108
char *mysql_unix_port= 0;
109
const char *unknown_sqlstate= "HY000";
110
const char *not_error_sqlstate= "00000";
111
const char *cant_connect_sqlstate= "08001";
113
char *shared_memory_base_name= 0;
114
const char *def_shared_memory_base_name= default_shared_memory_base_name;
117
static void mysql_close_free_options(MYSQL *mysql);
118
static void mysql_close_free(MYSQL *mysql);
120
#if !(defined(__WIN__) || defined(__NETWARE__))
121
static int wait_for_data(my_socket fd, uint timeout);
124
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
126
/* Server error code and message */
127
unsigned int mysql_server_last_errno;
128
char mysql_server_last_error[MYSQL_ERRMSG_SIZE];
130
/****************************************************************************
131
A modified version of connect(). my_connect() allows you to specify
132
a timeout value, in seconds, that we should wait until we
133
derermine we can't connect to a particular host. If timeout is 0,
134
my_connect() will behave exactly like connect().
136
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
137
*****************************************************************************/
139
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
142
#if defined(__WIN__) || defined(__NETWARE__)
143
return connect(fd, (struct sockaddr*) name, namelen);
145
int flags, res, s_err;
148
If they passed us a timeout of zero, we should behave
149
exactly like the normal connect() call does.
153
return connect(fd, (struct sockaddr*) name, namelen);
155
flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
157
fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
160
res= connect(fd, (struct sockaddr*) name, namelen);
161
s_err= errno; /* Save the error... */
162
fcntl(fd, F_SETFL, flags);
163
if ((res != 0) && (s_err != EINPROGRESS))
165
errno= s_err; /* Restore it */
168
if (res == 0) /* Connected quickly! */
170
return wait_for_data(fd, timeout);
176
Wait up to timeout seconds for a connection to be established.
178
We prefer to do this with poll() as there is no limitations with this.
179
If not, we will use select()
182
#if !(defined(__WIN__) || defined(__NETWARE__))
184
static int wait_for_data(my_socket fd, uint timeout)
191
ufds.events= POLLIN | POLLPRI;
192
if (!(res= poll(&ufds, 1, (int) timeout*1000)))
197
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
201
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
204
time_t start_time, now_time;
207
if (fd >= FD_SETSIZE) /* Check if wrong error */
208
return 0; /* Can't use timeout */
211
Our connection is "in progress." We can use the select() call to wait
212
up to a specified period of time for the connection to suceed.
213
If select() returns 0 (after waiting howevermany seconds), our socket
214
never became writable (host is probably unreachable.) Otherwise, if
215
select() returns 1, then one of two conditions exist:
217
1. An error occured. We use getsockopt() to check for this.
218
2. The connection was set up sucessfully: getsockopt() will
219
return 0 as an error.
221
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
222
who posted this method of timing out a connect() in
223
comp.unix.programmer on August 15th, 1997.
229
select could be interrupted by a signal, and if it is,
230
the timeout should be adjusted and the select restarted
231
to work around OSes that don't restart select and
232
implementations of select that don't adjust tv upon
233
failure to reflect the time remaining
235
start_time= my_time(0);
238
tv.tv_sec = (long) timeout;
241
if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
244
if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
247
if (res == 0) /* timeout */
249
now_time= my_time(0);
250
timeout-= (uint) (now_time - start_time);
251
if (errno != EINTR || (int) timeout <= 0)
256
select() returned something more interesting than zero, let's
257
see if we have any errors. If the next two statements pass,
258
we've got an open socket!
262
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
266
{ /* getsockopt could succeed */
268
return(-1); /* but return an error... */
271
#endif /* HAVE_POLL */
273
#endif /* defined(__WIN__) || defined(__NETWARE__) */
276
Set the internal error message to mysql handler
278
@param mysql connection handle (client side)
279
@param errcode CR_ error code, passed to ER macro to get
281
@parma sqlstate SQL standard sqlstate
284
void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate)
287
DBUG_ENTER("set_mysql_error");
288
DBUG_PRINT("enter", ("error :%d '%s'", errcode, ER(errcode)));
289
DBUG_ASSERT(mysql != 0);
294
net->last_errno= errcode;
295
strmov(net->last_error, ER(errcode));
296
strmov(net->sqlstate, sqlstate);
300
mysql_server_last_errno= errcode;
301
strmov(mysql_server_last_error, ER(errcode));
307
Clear possible error state of struct NET
309
@param net clear the state of the argument
312
void net_clear_error(NET *net)
315
net->last_error[0]= '\0';
316
strmov(net->sqlstate, not_error_sqlstate);
320
Set an error message on the client.
322
@param mysql connection handle
323
@param errcode CR_* errcode, for client errors
324
@param sqlstate SQL standard sql state, unknown_sqlstate for the
325
majority of client errors.
326
@param format error message template, in sprintf format
327
@param ... variable number of arguments
330
static void set_mysql_extended_error(MYSQL *mysql, int errcode,
331
const char *sqlstate,
332
const char *format, ...)
336
DBUG_ENTER("set_mysql_extended_error");
337
DBUG_PRINT("enter", ("error :%d '%s'", errcode, format));
338
DBUG_ASSERT(mysql != 0);
341
net->last_errno= errcode;
342
va_start(args, format);
343
vsnprintf(net->last_error, sizeof(net->last_error)-1,
346
strmov(net->sqlstate, sqlstate);
354
Create a named pipe connection
359
HANDLE create_named_pipe(MYSQL *mysql, uint connect_timeout, char **arg_host,
360
char **arg_unix_socket)
362
HANDLE hPipe=INVALID_HANDLE_VALUE;
363
char pipe_name[1024];
366
my_bool testing_named_pipes=0;
367
char *host= *arg_host, *unix_socket= *arg_unix_socket;
369
if ( ! unix_socket || (unix_socket)[0] == 0x00)
370
unix_socket = mysql_unix_port;
371
if (!host || !strcmp(host,LOCAL_HOST))
372
host=LOCAL_HOST_NAMEDPIPE;
375
pipe_name[sizeof(pipe_name)-1]= 0; /* Safety if too long string */
376
strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\", host, "\\pipe\\",
378
DBUG_PRINT("info",("Server name: '%s'. Named Pipe: %s", host, unix_socket));
380
for (i=0 ; i < 100 ; i++) /* Don't retry forever */
382
if ((hPipe = CreateFile(pipe_name,
383
GENERIC_READ | GENERIC_WRITE,
388
NULL )) != INVALID_HANDLE_VALUE)
390
if (GetLastError() != ERROR_PIPE_BUSY)
392
set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR,
393
unknown_sqlstate, ER(CR_NAMEDPIPEOPEN_ERROR),
394
host, unix_socket, (ulong) GetLastError());
395
return INVALID_HANDLE_VALUE;
397
/* wait for for an other instance */
398
if (! WaitNamedPipe(pipe_name, connect_timeout*1000) )
400
set_mysql_extended_error(mysql, CR_NAMEDPIPEWAIT_ERROR, unknown_sqlstate,
401
ER(CR_NAMEDPIPEWAIT_ERROR),
402
host, unix_socket, (ulong) GetLastError());
403
return INVALID_HANDLE_VALUE;
406
if (hPipe == INVALID_HANDLE_VALUE)
408
set_mysql_extended_error(mysql, CR_NAMEDPIPEOPEN_ERROR, unknown_sqlstate,
409
ER(CR_NAMEDPIPEOPEN_ERROR), host, unix_socket,
410
(ulong) GetLastError());
411
return INVALID_HANDLE_VALUE;
413
dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
414
if ( !SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) )
416
CloseHandle( hPipe );
417
set_mysql_extended_error(mysql, CR_NAMEDPIPESETSTATE_ERROR,
418
unknown_sqlstate, ER(CR_NAMEDPIPESETSTATE_ERROR),
419
host, unix_socket, (ulong) GetLastError());
420
return INVALID_HANDLE_VALUE;
422
*arg_host=host ; *arg_unix_socket=unix_socket; /* connect arg */
429
Create new shared memory connection, return handler of connection
432
create_shared_memory()
433
mysql Pointer of mysql structure
434
net Pointer of net structure
435
connect_timeout Timeout of connection
439
HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout)
441
ulong smem_buffer_length = shared_memory_buffer_length + 4;
443
event_connect_request is event object for start connection actions
444
event_connect_answer is event object for confirm, that server put data
445
handle_connect_file_map is file-mapping object, use for create shared
447
handle_connect_map is pointer on shared memory
448
handle_map is pointer on shared memory for client
452
event_client_read are events for transfer data between server and client
453
handle_file_map is file-mapping object, use for create shared memory
455
HANDLE event_connect_request = NULL;
456
HANDLE event_connect_answer = NULL;
457
HANDLE handle_connect_file_map = NULL;
458
char *handle_connect_map = NULL;
460
char *handle_map = NULL;
461
HANDLE event_server_wrote = NULL;
462
HANDLE event_server_read = NULL;
463
HANDLE event_client_wrote = NULL;
464
HANDLE event_client_read = NULL;
465
HANDLE event_conn_closed = NULL;
466
HANDLE handle_file_map = NULL;
467
ulong connect_number;
468
char connect_number_char[22], *p;
471
DWORD error_allow = 0;
472
DWORD error_code = 0;
473
DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE;
474
char *shared_memory_base_name = mysql->options.shared_memory_base_name;
477
get enough space base-name + '_' + longest suffix we might ever send
479
if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
483
The name of event and file-mapping events create agree next rule:
484
shared_memory_base_name+unique_part
486
shared_memory_base_name is unique value for each server
487
unique_part is uniquel value for each object (events and file-mapping)
489
suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", NullS);
490
strmov(suffix_pos, "CONNECT_REQUEST");
491
if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp)))
493
error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR;
496
strmov(suffix_pos, "CONNECT_ANSWER");
497
if (!(event_connect_answer= OpenEvent(event_access_rights,FALSE,tmp)))
499
error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR;
502
strmov(suffix_pos, "CONNECT_DATA");
503
if (!(handle_connect_file_map= OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)))
505
error_allow = CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR;
508
if (!(handle_connect_map= MapViewOfFile(handle_connect_file_map,
509
FILE_MAP_WRITE,0,0,sizeof(DWORD))))
511
error_allow = CR_SHARED_MEMORY_CONNECT_MAP_ERROR;
515
/* Send to server request of connection */
516
if (!SetEvent(event_connect_request))
518
error_allow = CR_SHARED_MEMORY_CONNECT_SET_ERROR;
522
/* Wait of answer from server */
523
if (WaitForSingleObject(event_connect_answer,connect_timeout*1000) !=
526
error_allow = CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR;
530
/* Get number of connection */
531
connect_number = uint4korr(handle_connect_map);/*WAX2*/
532
p= int10_to_str(connect_number, connect_number_char, 10);
535
The name of event and file-mapping events create agree next rule:
536
shared_memory_base_name+unique_part+number_of_connection
539
shared_memory_base_name is uniquel value for each server
540
unique_part is uniquel value for each object (events and file-mapping)
541
number_of_connection is number of connection between server and client
543
suffix_pos = strxmov(tmp, "Global\\", shared_memory_base_name, "_", connect_number_char,
545
strmov(suffix_pos, "DATA");
546
if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
548
error_allow = CR_SHARED_MEMORY_FILE_MAP_ERROR;
551
if ((handle_map = MapViewOfFile(handle_file_map,FILE_MAP_WRITE,0,0,
552
smem_buffer_length)) == NULL)
554
error_allow = CR_SHARED_MEMORY_MAP_ERROR;
558
strmov(suffix_pos, "SERVER_WROTE");
559
if ((event_server_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
561
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
565
strmov(suffix_pos, "SERVER_READ");
566
if ((event_server_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
568
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
572
strmov(suffix_pos, "CLIENT_WROTE");
573
if ((event_client_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
575
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
579
strmov(suffix_pos, "CLIENT_READ");
580
if ((event_client_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
582
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
586
strmov(suffix_pos, "CONNECTION_CLOSED");
587
if ((event_conn_closed = OpenEvent(event_access_rights,FALSE,tmp)) == NULL)
589
error_allow = CR_SHARED_MEMORY_EVENT_ERROR;
593
Set event that server should send data
595
SetEvent(event_server_read);
598
if (error_allow == 0)
600
net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
602
event_server_read,event_client_wrote,
603
event_client_read,event_conn_closed);
607
error_code = GetLastError();
608
if (event_server_read)
609
CloseHandle(event_server_read);
610
if (event_server_wrote)
611
CloseHandle(event_server_wrote);
612
if (event_client_read)
613
CloseHandle(event_client_read);
614
if (event_client_wrote)
615
CloseHandle(event_client_wrote);
616
if (event_conn_closed)
617
CloseHandle(event_conn_closed);
619
UnmapViewOfFile(handle_map);
621
CloseHandle(handle_file_map);
625
my_free(tmp, MYF(0));
627
error_code = GetLastError();
628
if (event_connect_request)
629
CloseHandle(event_connect_request);
630
if (event_connect_answer)
631
CloseHandle(event_connect_answer);
632
if (handle_connect_map)
633
UnmapViewOfFile(handle_connect_map);
634
if (handle_connect_file_map)
635
CloseHandle(handle_connect_file_map);
638
if (error_allow == CR_SHARED_MEMORY_EVENT_ERROR)
639
set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
640
ER(error_allow), suffix_pos, error_code);
642
set_mysql_extended_error(mysql, error_allow, unknown_sqlstate,
643
ER(error_allow), error_code);
644
return(INVALID_HANDLE_VALUE);
101
650
/*****************************************************************************
102
651
Read a packet from server. Give error message if socket was down
103
652
or packet is an error message
104
653
*****************************************************************************/
106
uint32_t cli_safe_read(DRIZZLE *drizzle)
656
cli_safe_read(MYSQL *mysql)
108
NET *net= &drizzle->net;
658
NET *net= &mysql->net;
660
init_sigpipe_variables
662
/* Don't give sigpipe errors if the client doesn't want them */
111
664
if (net->vio != 0)
112
665
len=my_net_read(net);
666
reset_sigpipe(mysql);
114
668
if (len == packet_error || len == 0)
116
#ifdef DRIZZLE_SERVER
670
DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %lu",
671
vio_description(net->vio),len));
117
673
if (net->vio && vio_was_interrupted(net->vio))
118
674
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());
675
#endif /*MYSQL_SERVER*/
677
set_mysql_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
678
CR_NET_PACKET_TOO_LARGE: CR_SERVER_LOST, unknown_sqlstate);
124
679
return (packet_error);
126
681
if (net->read_pos[0] == 255)
160
715
a multi-statement or a stored procedure, so it should be
161
716
safe to unconditionally turn off the flag here.
163
drizzle->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
718
mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
720
DBUG_PRINT("error",("Got error: %d/%s (%s)",
165
724
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());
729
void free_rows(MYSQL_DATA *cur)
733
free_root(&cur->alloc,MYF(0));
734
my_free((uchar*) cur,MYF(0));
739
cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
740
const uchar *header, ulong header_length,
741
const uchar *arg, ulong arg_length, my_bool skip_check)
743
NET *net= &mysql->net;
745
init_sigpipe_variables
746
my_bool stmt_skip= FALSE;
747
DBUG_ENTER("cli_advanced_command");
749
/* Don't give sigpipe errors if the client doesn't want them */
752
if (mysql->net.vio == 0)
753
{ /* Do reconnect if possible */
754
if (mysql_reconnect(mysql) || stmt_skip)
757
if (mysql->status != MYSQL_STATUS_READY ||
758
mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
760
DBUG_PRINT("error",("state: %d", mysql->status));
761
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
192
765
net_clear_error(net);
194
drizzle->affected_rows= ~(uint64_t) 0;
767
mysql->affected_rows= ~(my_ulonglong) 0;
196
769
We don't want to clear the protocol buffer on COM_QUIT, because if
197
770
the previous command was a shutdown command, we may have the
198
771
response for the COM_QUIT already in the communication buffer
200
net_clear(&drizzle->net, (command != COM_QUIT));
773
net_clear(&mysql->net, (command != COM_QUIT));
202
if (net_write_command(net,(unsigned char) command, header, header_length,
775
if (net_write_command(net,(uchar) command, header, header_length,
205
if (net->last_errno == CR_NET_PACKET_TOO_LARGE)
778
DBUG_PRINT("error",("Can't send command to server. Error: %d",
780
if (net->last_errno == ER_NET_PACKET_TOO_LARGE)
207
drizzle_set_error(drizzle, CR_NET_PACKET_TOO_LARGE, sqlstate_get_unknown());
782
set_mysql_error(mysql, CR_NET_PACKET_TOO_LARGE, unknown_sqlstate);
210
drizzle_disconnect(drizzle);
211
if (drizzle_reconnect(drizzle) || stmt_skip)
786
if (mysql_reconnect(mysql) || stmt_skip)
213
if (net_write_command(net,(unsigned char) command, header, header_length,
788
if (net_write_command(net,(uchar) command, header, header_length,
216
drizzle_set_error(drizzle, CR_SERVER_GONE_ERROR, sqlstate_get_unknown());
791
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
222
result= ((drizzle->packet_length=cli_safe_read(drizzle)) == packet_error ?
797
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)
800
reset_sigpipe(mysql);
801
DBUG_PRINT("exit",("result: %d", result));
805
void free_old_query(MYSQL *mysql)
807
DBUG_ENTER("free_old_query");
809
free_root(&mysql->field_alloc,MYF(0));
810
init_alloc_root(&mysql->field_alloc,8192,0); /* Assume rowlength < 8192 */
812
mysql->field_count= 0; /* For API */
813
mysql->warning_count= 0;
819
Flush result set sent from server
822
static void cli_flush_use_result(MYSQL *mysql)
824
/* Clear the current execution status */
825
DBUG_ENTER("cli_flush_use_result");
826
DBUG_PRINT("warning",("Not all packets read, clearing them"));
830
if ((pkt_len=cli_safe_read(mysql)) == packet_error)
832
if (pkt_len <= 8 && mysql->net.read_pos[0] == 254)
834
if (protocol_41(mysql))
836
char *pos= (char*) mysql->net.read_pos + 1;
837
mysql->warning_count=uint2korr(pos); pos+=2;
838
mysql->server_status=uint2korr(pos); pos+=2;
840
break; /* End of data */
848
static my_bool is_NT(void)
850
char *os=getenv("OS");
851
return (os && !strcmp(os, "Windows_NT")) ? 1 : 0;
858
Check server side variable 'license'.
860
If the variable does not exist or does not contain 'Commercial',
861
we're talking to non-commercial server from commercial client.
864
@retval !0 network error or the server is not commercial.
865
Error code is saved in mysql->net.last_errno.
868
static int check_license(MYSQL *mysql)
872
NET *net= &mysql->net;
873
static const char query[]= "SELECT @@license";
874
static const char required_license[]= STRINGIFY_ARG(LICENSE);
876
if (mysql_real_query(mysql, query, sizeof(query)-1))
878
if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
880
set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
881
ER(CR_WRONG_LICENSE), required_license);
885
if (!(res= mysql_use_result(mysql)))
887
row= mysql_fetch_row(res);
889
If no rows in result set, or column value is NULL (none of these
890
two is ever true for server variables now), or column value
891
mismatch, set wrong license error.
893
if (!net->last_errno &&
895
strncmp(row[0], required_license, sizeof(required_license))))
897
set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
898
ER(CR_WRONG_LICENSE), required_license);
900
mysql_free_result(res);
901
return net->last_errno;
903
#endif /* CHECK_LICENSE */
906
/**************************************************************************
908
**************************************************************************/
910
void end_server(MYSQL *mysql)
912
int save_errno= errno;
913
DBUG_ENTER("end_server");
914
if (mysql->net.vio != 0)
916
init_sigpipe_variables
917
DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio)));
919
vio_delete(mysql->net.vio);
920
reset_sigpipe(mysql);
921
mysql->net.vio= 0; /* Marker */
923
net_end(&mysql->net);
924
free_old_query(mysql);
931
mysql_free_result(MYSQL_RES *result)
933
DBUG_ENTER("mysql_free_result");
934
DBUG_PRINT("enter",("mysql_res: 0x%lx", (long) result));
260
DRIZZLE *drizzle= result->handle;
937
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)
940
if (mysql->unbuffered_fetch_owner == &result->unbuffered_fetch_cancelled)
941
mysql->unbuffered_fetch_owner= 0;
942
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;
944
(*mysql->methods->flush_use_result)(mysql);
945
mysql->status=MYSQL_STATUS_READY;
946
if (mysql->unbuffered_fetch_owner)
947
*mysql->unbuffered_fetch_owner= TRUE;
273
950
free_rows(result->data);
274
/* TODO: free result->fields */
952
free_root(&result->field_alloc,MYF(0));
276
free((unsigned char*) result->row);
277
free((unsigned char*) result);
954
my_free((uchar*) result->row,MYF(0));
955
my_free((uchar*) result,MYF(0));
960
/****************************************************************************
961
Get options from my.cnf
962
****************************************************************************/
964
static const char *default_options[]=
966
"port","socket","compress","password","pipe", "timeout", "user",
967
"init-command", "host", "database", "debug", "return-found-rows",
968
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
969
"character-sets-dir", "default-character-set", "interactive-timeout",
970
"connect-timeout", "local-infile", "disable-local-infile",
971
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
972
"multi-results", "multi-statements", "multi-queries", "secure-auth",
973
"report-data-truncation",
977
static TYPELIB option_types={array_elements(default_options)-1,
978
"options",default_options, NULL};
980
const char *sql_protocol_names_lib[] =
981
{ "TCP", "SOCKET", "PIPE", "MEMORY", NullS };
982
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
983
sql_protocol_names_lib, NULL};
985
static int add_init_command(struct st_mysql_options *options, const char *cmd)
989
if (!options->init_commands)
991
options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
993
init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
996
if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
997
insert_dynamic(options->init_commands, (uchar*)&tmp))
999
my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
1006
void mysql_read_default_options(struct st_mysql_options *options,
1007
const char *filename,const char *group)
1010
char *argv_buff[1],**argv;
1011
const char *groups[3];
1012
DBUG_ENTER("mysql_read_default_options");
1013
DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL"));
1015
argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
1016
groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
1018
load_defaults(filename, groups, &argc, &argv);
1019
if (argc != 1) /* If some default option */
1024
/* DBUG_PRINT("info",("option: %s",option[0])); */
1025
if (option[0][0] == '-' && option[0][1] == '-')
1027
char *end=strcend(*option,'=');
1032
*end=0; /* Remove '=' */
1034
/* Change all '_' in variable name to '-' */
1035
for (end= *option ; *(end= strcend(end,'_')) ; )
1037
switch (find_type(*option+2,&option_types,2)) {
1040
options->port=atoi(opt_arg);
1042
case 2: /* socket */
1045
my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
1046
options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
1049
case 3: /* compress */
1050
options->compress=1;
1051
options->client_flag|= CLIENT_COMPRESS;
1053
case 4: /* password */
1056
my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
1057
options->password=my_strdup(opt_arg,MYF(MY_WME));
1061
options->protocol = MYSQL_PROTOCOL_PIPE;
1062
case 20: /* connect_timeout */
1063
case 6: /* timeout */
1065
options->connect_timeout=atoi(opt_arg);
1070
my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
1071
options->user=my_strdup(opt_arg,MYF(MY_WME));
1074
case 8: /* init-command */
1075
add_init_command(options,opt_arg);
1080
my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
1081
options->host=my_strdup(opt_arg,MYF(MY_WME));
1084
case 10: /* database */
1087
my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
1088
options->db=my_strdup(opt_arg,MYF(MY_WME));
1091
case 11: /* debug */
1093
mysql_debug(opt_arg ? opt_arg : "d:t:o,/tmp/client.trace");
1096
case 12: /* return-found-rows */
1097
options->client_flag|=CLIENT_FOUND_ROWS;
1099
case 13: /* Ignore SSL options */
1105
case 17: /* charset-lib */
1106
my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
1107
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
1110
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
1111
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
1113
case 19: /* Interactive-timeout */
1114
options->client_flag|= CLIENT_INTERACTIVE;
1117
if (!opt_arg || atoi(opt_arg) != 0)
1118
options->client_flag|= CLIENT_LOCAL_FILES;
1120
options->client_flag&= ~CLIENT_LOCAL_FILES;
1123
options->client_flag&= ~CLIENT_LOCAL_FILES;
1125
case 24: /* max-allowed-packet */
1127
options->max_allowed_packet= atoi(opt_arg);
1129
case 25: /* protocol */
1130
if ((options->protocol= find_type(opt_arg,
1131
&sql_protocol_typelib,0)) <= 0)
1133
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
1137
case 26: /* shared_memory_base_name */
1139
if (options->shared_memory_base_name != def_shared_memory_base_name)
1140
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
1141
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
1144
case 27: /* multi-results */
1145
options->client_flag|= CLIENT_MULTI_RESULTS;
1147
case 28: /* multi-statements */
1148
case 29: /* multi-queries */
1149
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
1151
case 30: /* secure-auth */
1152
options->secure_auth= TRUE;
1154
case 31: /* report-data-truncation */
1155
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
1158
DBUG_PRINT("warning",("unknown option: %s",option[0]));
1163
free_defaults(argv);
1168
/**************************************************************************
1169
Get column lengths of the current row
1170
If one uses mysql_use_result, res->lengths contains the length information,
1171
else the lengths are calculated from the offset between pointers.
1172
**************************************************************************/
1174
static void cli_fetch_lengths(ulong *to, MYSQL_ROW column,
1175
unsigned int field_count)
1181
prev_length=0; /* Keep gcc happy */
1182
for (end=column + field_count + 1 ; column != end ; column++, to++)
1189
if (start) /* Found end of prev string */
1190
*prev_length= (ulong) (*column-start-1);
1196
/***************************************************************************
1197
Change field rows to field structs
1198
***************************************************************************/
1201
unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
1202
my_bool default_value, uint server_capabilities)
1205
MYSQL_FIELD *field,*result;
1206
ulong lengths[9]; /* Max of fields */
1207
DBUG_ENTER("unpack_fields");
1209
field= result= (MYSQL_FIELD*) alloc_root(alloc,
1210
(uint) sizeof(*field)*fields);
1213
free_rows(data); /* Free old data */
1216
bzero((char*) field, (uint) sizeof(MYSQL_FIELD)*fields);
1217
if (server_capabilities & CLIENT_PROTOCOL_41)
1219
/* server is 4.1, and returns the new field result format */
1220
for (row=data->data; row ; row = row->next,field++)
1223
/* fields count may be wrong */
1224
DBUG_ASSERT((uint) (field - result) < fields);
1225
cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
1226
field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]);
1227
field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]);
1228
field->table= strmake_root(alloc,(char*) row->data[2], lengths[2]);
1229
field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]);
1230
field->name= strmake_root(alloc,(char*) row->data[4], lengths[4]);
1231
field->org_name= strmake_root(alloc,(char*) row->data[5], lengths[5]);
1233
field->catalog_length= lengths[0];
1234
field->db_length= lengths[1];
1235
field->table_length= lengths[2];
1236
field->org_table_length= lengths[3];
1237
field->name_length= lengths[4];
1238
field->org_name_length= lengths[5];
1240
/* Unpack fixed length parts */
1241
pos= (uchar*) row->data[6];
1242
field->charsetnr= uint2korr(pos);
1243
field->length= (uint) uint4korr(pos+2);
1244
field->type= (enum enum_field_types) pos[6];
1245
field->flags= uint2korr(pos+7);
1246
field->decimals= (uint) pos[9];
1248
if (INTERNAL_NUM_FIELD(field))
1249
field->flags|= NUM_FLAG;
1250
if (default_value && row->data[7])
1252
field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]);
1253
field->def_length= lengths[7];
1257
field->max_length= 0;
1260
#ifndef DELETE_SUPPORT_OF_4_0_PROTOCOL
1263
/* old protocol, for backward compatibility */
1264
for (row=data->data; row ; row = row->next,field++)
1266
cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
1267
field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
1268
field->name= strdup_root(alloc,(char*) row->data[1]);
1269
field->length= (uint) uint3korr(row->data[2]);
1270
field->type= (enum enum_field_types) (uchar) row->data[3][0];
1272
field->catalog=(char*) "";
1273
field->db= (char*) "";
1274
field->catalog_length= 0;
1275
field->db_length= 0;
1276
field->org_table_length= field->table_length= lengths[0];
1277
field->name_length= lengths[1];
1279
if (server_capabilities & CLIENT_LONG_FLAG)
1281
field->flags= uint2korr(row->data[4]);
1282
field->decimals=(uint) (uchar) row->data[4][2];
1286
field->flags= (uint) (uchar) row->data[4][0];
1287
field->decimals=(uint) (uchar) row->data[4][1];
1289
if (INTERNAL_NUM_FIELD(field))
1290
field->flags|= NUM_FLAG;
1291
if (default_value && row->data[5])
1293
field->def=strdup_root(alloc,(char*) row->data[5]);
1294
field->def_length= lengths[5];
1298
field->max_length= 0;
1301
#endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */
1302
free_rows(data); /* Free old data */
1303
DBUG_RETURN(result);
284
1306
/* Read all rows (fields or data) from server */
286
DRIZZLE_DATA *cli_read_rows(DRIZZLE *drizzle, DRIZZLE_FIELD *DRIZZLE_FIELDs, uint32_t fields)
1308
MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
1309
unsigned int fields)
293
DRIZZLE_DATA *result;
294
DRIZZLE_ROWS **prev_ptr,*cur;
295
NET *net = &drizzle->net;
1317
MYSQL_ROWS **prev_ptr,*cur;
1318
NET *net = &mysql->net;
1319
DBUG_ENTER("cli_read_rows");
297
if ((pkt_len= cli_safe_read(drizzle)) == packet_error)
299
if (!(result=(DRIZZLE_DATA*) malloc(sizeof(DRIZZLE_DATA))))
1321
if ((pkt_len= cli_safe_read(mysql)) == packet_error)
1323
if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
1324
MYF(MY_WME | MY_ZEROFILL))))
301
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY,
302
sqlstate_get_unknown());
1326
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
305
memset(result, 0, sizeof(DRIZZLE_DATA));
1329
init_alloc_root(&result->alloc,8192,0); /* Assume rowlength < 8192 */
1330
result->alloc.min_malloc=sizeof(MYSQL_ROWS);
306
1331
prev_ptr= &result->data;
308
1333
result->fields=fields;
311
The last EOF packet is either a 254 (0xFE) character followed by 1-7 status bytes.
1336
The last EOF packet is either a single 254 character or (in MySQL 4.1)
1337
254 followed by 1-7 status bytes.
313
1339
This doesn't conflict with normal usage of 254 which stands for a
314
1340
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)
1343
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))))
1346
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
1347
sizeof(MYSQL_ROWS))) ||
1348
!(cur->data= ((MYSQL_ROW)
1349
alloc_root(&result->alloc,
1350
(fields+1)*sizeof(char *)+pkt_len))))
323
1352
free_rows(result);
324
drizzle_set_error(drizzle, CR_OUT_OF_MEMORY, sqlstate_get_unknown());
1353
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
328
1357
prev_ptr= &cur->next;
422
*prev_pos=0; /* Terminate prev field */
1451
*prev_pos=0; /* Terminate prev field */
425
row[field]=(char*) prev_pos+1; /* End of last field */
426
*prev_pos=0; /* Terminate last field */
1454
row[field]=(char*) prev_pos+1; /* End of last field */
1455
*prev_pos=0; /* Terminate last field */
1460
/****************************************************************************
1461
Init MySQL structure or allocate one
1462
****************************************************************************/
1465
mysql_init(MYSQL *mysql)
1467
if (mysql_server_init(0, NULL, NULL))
1471
if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
1473
set_mysql_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
1479
bzero((char*) (mysql), sizeof(*(mysql)));
1480
mysql->options.connect_timeout= CONNECT_TIMEOUT;
1481
mysql->charset=default_client_charset_info;
1482
strmov(mysql->net.sqlstate, not_error_sqlstate);
1485
Only enable LOAD DATA INFILE by default if configured with
1486
--enable-local-infile
1489
#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER)
1490
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
1494
mysql->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
1497
mysql->options.methods_to_use= MYSQL_OPT_GUESS_CONNECTION;
1498
mysql->options.report_data_truncation= TRUE; /* default */
1501
By default we don't reconnect because it could silently corrupt data (after
1502
reconnection you potentially lose table locks, user variables, session
1503
variables (transactions but they are specifically dealt with in
1505
This is a change: < 5.0.3 mysql->reconnect was set to 1 by default.
1506
How this change impacts existing apps:
1507
- existing apps which relyed on the default will see a behaviour change;
1508
they will have to set reconnect=1 after mysql_real_connect().
1509
- existing apps which explicitely asked for reconnection (the only way they
1510
could do it was by setting mysql.reconnect to 1 after mysql_real_connect())
1511
will not see a behaviour change.
1512
- existing apps which explicitely asked for no reconnection
1513
(mysql.reconnect=0) will not see a behaviour change.
1515
mysql->reconnect= 0;
1522
Fill in SSL part of MYSQL structure and set 'use_ssl' flag.
1523
NB! Errors are not reported until you do mysql_real_connect.
1526
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
1529
mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
1530
const char *key __attribute__((unused)),
1531
const char *cert __attribute__((unused)),
1532
const char *ca __attribute__((unused)),
1533
const char *capath __attribute__((unused)),
1534
const char *cipher __attribute__((unused)))
1536
DBUG_ENTER("mysql_ssl_set");
1542
Free strings in the SSL structure and clear 'use_ssl' flag.
1543
NB! Errors are not reported until you do mysql_real_connect.
1547
Return the SSL cipher (if any) used for current
1548
connection to the server.
1551
mysql_get_ssl_cipher()
1552
mysql pointer to the mysql connection
1556
const char * STDCALL
1557
mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused)))
1559
DBUG_ENTER("mysql_get_ssl_cipher");
1565
Check the server's (subject) Common Name against the
1566
hostname we connected to
1569
ssl_verify_server_cert()
1570
vio pointer to a SSL connected vio
1571
server_hostname name of the server that we connected to
1575
1 Failed to validate server
1581
Note that the mysql argument must be initialized with mysql_init()
1582
before calling mysql_real_connect !
1585
static my_bool cli_read_query_result(MYSQL *mysql);
1586
static MYSQL_RES *cli_use_result(MYSQL *mysql);
1588
static MYSQL_METHODS client_methods=
1590
cli_read_query_result, /* read_query_result */
1591
cli_advanced_command, /* advanced_command */
1592
cli_read_rows, /* read_rows */
1593
cli_use_result, /* use_result */
1594
cli_fetch_lengths, /* fetch_lengths */
1595
cli_flush_use_result, /* flush_use_result */
1596
#ifndef MYSQL_SERVER
1597
cli_list_fields, /* list_fields */
1598
cli_unbuffered_fetch, /* unbuffered_fetch */
1599
cli_read_statistics, /* read_statistics */
1600
cli_read_query_result, /* next_result */
1601
cli_read_change_user_result, /* read_change_user_result */
1608
int mysql_init_character_set(MYSQL *mysql)
1610
const char *default_collation_name;
1612
/* Set character set */
1613
if (!mysql->options.charset_name)
1615
default_collation_name= MYSQL_DEFAULT_COLLATION_NAME;
1616
if (!(mysql->options.charset_name=
1617
my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
1621
default_collation_name= NULL;
1624
const char *save= charsets_dir;
1625
if (mysql->options.charset_dir)
1626
charsets_dir=mysql->options.charset_dir;
1627
mysql->charset=get_charset_by_csname(mysql->options.charset_name,
1628
MY_CS_PRIMARY, MYF(MY_WME));
1629
if (mysql->charset && default_collation_name)
1631
CHARSET_INFO *collation;
1633
get_charset_by_name(default_collation_name, MYF(MY_WME))))
1635
if (!my_charset_same(mysql->charset, collation))
1637
my_printf_error(ER_UNKNOWN_ERROR,
1638
"COLLATION %s is not valid for CHARACTER SET %s",
1640
default_collation_name, mysql->options.charset_name);
1641
mysql->charset= NULL;
1645
mysql->charset= collation;
1649
mysql->charset= NULL;
1654
if (!mysql->charset)
1656
if (mysql->options.charset_dir)
1657
set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
1658
ER(CR_CANT_READ_CHARSET),
1659
mysql->options.charset_name,
1660
mysql->options.charset_dir);
1663
char cs_dir_name[FN_REFLEN];
1664
get_charsets_dir(cs_dir_name);
1665
set_mysql_extended_error(mysql, CR_CANT_READ_CHARSET, unknown_sqlstate,
1666
ER(CR_CANT_READ_CHARSET),
1667
mysql->options.charset_name,
1678
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
1679
const char *passwd, const char *db,
1680
uint port, const char *unix_socket,ulong client_flag)
1682
char buff[NAME_LEN+USERNAME_LENGTH+100];
1683
char *end,*host_info;
1685
NET *net= &mysql->net;
1687
thr_alarm_t alarmed;
1691
HANDLE hPipe=INVALID_HANDLE_VALUE;
1693
#ifdef HAVE_SYS_UN_H
1694
struct sockaddr_un UNIXaddr;
1696
init_sigpipe_variables
1697
DBUG_ENTER("mysql_real_connect");
1699
DBUG_PRINT("enter",("host: %s db: %s user: %s",
1700
host ? host : "(Null)",
1702
user ? user : "(Null)"));
1704
/* Don't give sigpipe errors if the client doesn't want them */
1706
mysql->methods= &client_methods;
1707
net->vio = 0; /* If something goes wrong */
1708
mysql->client_flag=0; /* For handshake */
1710
/* use default options */
1711
if (mysql->options.my_cnf_file || mysql->options.my_cnf_group)
1713
mysql_read_default_options(&mysql->options,
1714
(mysql->options.my_cnf_file ?
1715
mysql->options.my_cnf_file : "my"),
1716
mysql->options.my_cnf_group);
1717
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1718
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1719
mysql->options.my_cnf_file=mysql->options.my_cnf_group=0;
1722
/* Some empty-string-tests are done because of ODBC */
1723
if (!host || !host[0])
1724
host=mysql->options.host;
1725
if (!user || !user[0])
1727
user=mysql->options.user;
1733
passwd=mysql->options.password;
1734
#if !defined(DONT_USE_MYSQL_PWD) && !defined(MYSQL_SERVER)
1736
passwd=getenv("MYSQL_PWD"); /* get it from environment */
1742
db=mysql->options.db;
1744
port=mysql->options.port;
1746
unix_socket=mysql->options.unix_socket;
1748
mysql->server_status=SERVER_STATUS_AUTOCOMMIT;
1751
Part 0: Grab a socket and connect it to the server
1753
#if defined(HAVE_SMEM)
1754
if ((!mysql->options.protocol ||
1755
mysql->options.protocol == MYSQL_PROTOCOL_MEMORY) &&
1756
(!host || !strcmp(host,LOCAL_HOST)))
1758
if ((create_shared_memory(mysql,net, mysql->options.connect_timeout)) ==
1759
INVALID_HANDLE_VALUE)
1762
("host: '%s' socket: '%s' shared memory: %s have_tcpip: %d",
1763
host ? host : "<null>",
1764
unix_socket ? unix_socket : "<null>",
1765
(int) mysql->options.shared_memory_base_name,
1767
if (mysql->options.protocol == MYSQL_PROTOCOL_MEMORY)
1771
Try also with PIPE or TCP/IP. Clear the error from
1772
create_shared_memory().
1775
net_clear_error(net);
1779
mysql->options.protocol=MYSQL_PROTOCOL_MEMORY;
1781
host=mysql->options.shared_memory_base_name;
1782
snprintf(host_info=buff, sizeof(buff)-1,
1783
ER(CR_SHARED_MEMORY_CONNECTION), host);
1786
#endif /* HAVE_SMEM */
1787
#if defined(HAVE_SYS_UN_H)
1789
(!mysql->options.protocol ||
1790
mysql->options.protocol == MYSQL_PROTOCOL_SOCKET) &&
1791
(unix_socket || mysql_unix_port) &&
1792
(!host || !strcmp(host,LOCAL_HOST)))
1794
my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
1795
if (sock == SOCKET_ERROR)
1797
set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR,
1799
ER(CR_SOCKET_CREATE_ERROR),
1804
net->vio= vio_new(sock, VIO_TYPE_SOCKET,
1805
VIO_LOCALHOST | VIO_BUFFERED_READ);
1808
DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
1809
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1816
unix_socket= mysql_unix_port;
1817
host_info= (char*) ER(CR_LOCALHOST_CONNECTION);
1818
DBUG_PRINT("info", ("Using UNIX sock '%s'", unix_socket));
1820
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
1821
UNIXaddr.sun_family= AF_UNIX;
1822
strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);
1824
if (my_connect(sock, (struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
1825
mysql->options.connect_timeout))
1827
DBUG_PRINT("error",("Got error %d on connect to local server",
1829
set_mysql_extended_error(mysql, CR_CONNECTION_ERROR,
1831
ER(CR_CONNECTION_ERROR),
1832
unix_socket, socket_errno);
1833
vio_delete(net->vio);
1837
mysql->options.protocol=MYSQL_PROTOCOL_SOCKET;
1839
#elif defined(__WIN__)
1841
(mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1842
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1843
(! have_tcpip && (unix_socket || !host && is_NT()))))
1845
if ((hPipe= create_named_pipe(mysql, mysql->options.connect_timeout,
1846
(char**) &host, (char**) &unix_socket)) ==
1847
INVALID_HANDLE_VALUE)
1850
("host: '%s' socket: '%s' have_tcpip: %d",
1851
host ? host : "<null>",
1852
unix_socket ? unix_socket : "<null>",
1854
if (mysql->options.protocol == MYSQL_PROTOCOL_PIPE ||
1855
(host && !strcmp(host,LOCAL_HOST_NAMEDPIPE)) ||
1856
(unix_socket && !strcmp(unix_socket,MYSQL_NAMEDPIPE)))
1858
/* Try also with TCP/IP */
1862
net->vio=vio_new_win32pipe(hPipe);
1863
snprintf(host_info=buff, sizeof(buff)-1,
1864
ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
1869
(!mysql->options.protocol ||
1870
mysql->options.protocol == MYSQL_PROTOCOL_TCP))
1872
struct addrinfo *res_lst, hints, *t_res;
1874
char port_buf[NI_MAXSERV];
1876
unix_socket=0; /* This is not used */
1884
snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
1885
DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host, port));
1887
thr_alarm_init(&alarmed);
1888
thr_alarm(&alarmed, mysql->options.connect_timeout, &alarm_buff);
1891
DBUG_PRINT("info",("IP '%s'", "client"));
1894
thr_end_alarm(&alarmed);
1897
memset(&hints, 0, sizeof(hints));
1898
hints.ai_socktype= SOCK_STREAM;
1899
hints.ai_protocol= IPPROTO_TCP;
1900
hints.ai_family= AF_UNSPEC;
1902
DBUG_PRINT("info",("IPV6 getaddrinfo %s", host));
1903
snprintf(port_buf, NI_MAXSERV, "%d", port);
1904
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
1909
For DBUG we are keeping the right message but for client we default to
1910
historical error message.
1912
DBUG_PRINT("info",("IPV6 getaddrinfo error %d", gai_errno));
1913
set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
1914
ER(CR_UNKNOWN_HOST), host, errno);
1919
/* We only look at the first item (something to think about changing in the future) */
1922
my_socket sock= socket(t_res->ai_family, t_res->ai_socktype,
1923
t_res->ai_protocol);
1924
if (sock == SOCKET_ERROR)
1926
set_mysql_extended_error(mysql, CR_IPSOCK_ERROR, unknown_sqlstate,
1927
ER(CR_IPSOCK_ERROR), socket_errno);
1928
freeaddrinfo(res_lst);
1932
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
1935
DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol));
1936
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1938
freeaddrinfo(res_lst);
1942
if (my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
1943
mysql->options.connect_timeout))
1945
DBUG_PRINT("error",("Got error %d on connect to '%s'",socket_errno,
1947
set_mysql_extended_error(mysql, CR_CONN_HOST_ERROR, unknown_sqlstate,
1948
ER(CR_CONN_HOST_ERROR), host, socket_errno);
1949
vio_delete(net->vio);
1951
freeaddrinfo(res_lst);
1956
freeaddrinfo(res_lst);
1961
DBUG_PRINT("error",("Unknow protocol %d ",mysql->options.protocol));
1962
set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1966
if (my_net_init(net, net->vio))
1968
vio_delete(net->vio);
1970
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1973
vio_keepalive(net->vio,TRUE);
1975
/* If user set read_timeout, let it override the default */
1976
if (mysql->options.read_timeout)
1977
my_net_set_read_timeout(net, mysql->options.read_timeout);
1979
/* If user set write_timeout, let it override the default */
1980
if (mysql->options.write_timeout)
1981
my_net_set_write_timeout(net, mysql->options.write_timeout);
1983
if (mysql->options.max_allowed_packet)
1984
net->max_packet_size= mysql->options.max_allowed_packet;
1986
/* Get version info */
1987
mysql->protocol_version= PROTOCOL_VERSION; /* Assume this */
1988
if (mysql->options.connect_timeout &&
1989
vio_poll_read(net->vio, mysql->options.connect_timeout))
1991
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
1992
ER(CR_SERVER_LOST_EXTENDED),
1993
"waiting for initial communication packet",
1999
Part 1: Connection established, read and parse first packet
2002
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
2004
if (mysql->net.last_errno == CR_SERVER_LOST)
2005
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2006
ER(CR_SERVER_LOST_EXTENDED),
2007
"reading initial communication packet",
2011
/* Check if version of protocol matches current one */
2013
mysql->protocol_version= net->read_pos[0];
2014
DBUG_DUMP("packet",(uchar*) net->read_pos,10);
2015
DBUG_PRINT("info",("mysql protocol version %d, server=%d",
2016
PROTOCOL_VERSION, mysql->protocol_version));
2017
if (mysql->protocol_version != PROTOCOL_VERSION)
2019
set_mysql_extended_error(mysql, CR_VERSION_ERROR, unknown_sqlstate,
2020
ER(CR_VERSION_ERROR), mysql->protocol_version,
2024
end=strend((char*) net->read_pos+1);
2025
mysql->thread_id=uint4korr(end+1);
2028
Scramble is split into two parts because old clients does not understand
2029
long scrambles; here goes the first part.
2031
strmake(mysql->scramble, end, SCRAMBLE_LENGTH_323);
2032
end+= SCRAMBLE_LENGTH_323+1;
2034
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
2035
mysql->server_capabilities=uint2korr(end);
2036
if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
2038
/* New protocol with 16 bytes to describe server characteristics */
2039
mysql->server_language=end[2];
2040
mysql->server_status=uint2korr(end+3);
2043
if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
2044
(char *) net->read_pos))
2045
strmake(mysql->scramble+SCRAMBLE_LENGTH_323, end,
2046
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
2048
mysql->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
2050
if (mysql->options.secure_auth && passwd[0] &&
2051
!(mysql->server_capabilities & CLIENT_SECURE_CONNECTION))
2053
set_mysql_error(mysql, CR_SECURE_AUTH, unknown_sqlstate);
2057
if (mysql_init_character_set(mysql))
2060
/* Save connection information */
2061
if (!my_multi_malloc(MYF(0),
2062
&mysql->host_info, (uint) strlen(host_info)+1,
2063
&mysql->host, (uint) strlen(host)+1,
2064
&mysql->unix_socket,unix_socket ?
2065
(uint) strlen(unix_socket)+1 : (uint) 1,
2066
&mysql->server_version,
2067
(uint) (end - (char*) net->read_pos),
2069
!(mysql->user=my_strdup(user,MYF(0))) ||
2070
!(mysql->passwd=my_strdup(passwd,MYF(0))))
2072
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
2075
strmov(mysql->host_info,host_info);
2076
strmov(mysql->host,host);
2078
strmov(mysql->unix_socket,unix_socket);
2080
mysql->unix_socket=0;
2081
strmov(mysql->server_version,(char*) net->read_pos+1);
2085
Part 2: format and send client info to the server for access check
2088
client_flag|=mysql->options.client_flag;
2089
client_flag|=CLIENT_CAPABILITIES;
2090
if (client_flag & CLIENT_MULTI_STATEMENTS)
2091
client_flag|= CLIENT_MULTI_RESULTS;
2094
client_flag|=CLIENT_CONNECT_WITH_DB;
2096
/* Remove options that server doesn't support */
2097
client_flag= ((client_flag &
2098
~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
2099
(client_flag & mysql->server_capabilities));
2100
client_flag&= ~CLIENT_COMPRESS;
2102
if (client_flag & CLIENT_PROTOCOL_41)
2104
/* 4.1 server and 4.1 client has a 32 byte option flag */
2105
int4store(buff,client_flag);
2106
int4store(buff+4, net->max_packet_size);
2107
buff[8]= (char) mysql->charset->number;
2108
bzero(buff+9, 32-9);
2113
int2store(buff,client_flag);
2114
int3store(buff+2,net->max_packet_size);
2117
mysql->client_flag=client_flag;
2119
DBUG_PRINT("info",("Server version = '%s' capabilites: %lu status: %u client_flag: %lu",
2120
mysql->server_version,mysql->server_capabilities,
2121
mysql->server_status, client_flag));
2122
/* This needs to be changed as it's not useful with big packets */
2123
if (user && user[0])
2124
strmake(end,user,USERNAME_LENGTH); /* Max user name */
2126
read_user_name((char*) end);
2128
/* We have to handle different version of handshake here */
2129
#ifdef _CUSTOMCONFIG_
2130
#include "_cust_libmysql.h"
2132
DBUG_PRINT("info",("user: %s",end));
2133
end= strend(end) + 1;
2136
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2138
*end++= SCRAMBLE_LENGTH;
2139
scramble(end, mysql->scramble, passwd);
2140
end+= SCRAMBLE_LENGTH;
2144
scramble_323(end, mysql->scramble, passwd);
2145
end+= SCRAMBLE_LENGTH_323 + 1;
2149
*end++= '\0'; /* empty password */
2151
/* Add database if needed */
2152
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
2154
end= strmake(end, db, NAME_LEN) + 1;
2155
mysql->db= my_strdup(db,MYF(MY_WME));
2158
/* Write authentication package */
2159
if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
2161
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2162
ER(CR_SERVER_LOST_EXTENDED),
2163
"sending authentication information",
2169
Part 3: Authorization data's been sent. Now server can reply with
2170
OK-packet, or re-request scrambled password.
2173
if ((pkt_length=cli_safe_read(mysql)) == packet_error)
2175
if (mysql->net.last_errno == CR_SERVER_LOST)
2176
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2177
ER(CR_SERVER_LOST_EXTENDED),
2178
"reading authorization packet",
2183
if (pkt_length == 1 && net->read_pos[0] == 254 &&
2184
mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
2187
By sending this very specific reply server asks us to send scrambled
2188
password in old format.
2190
scramble_323(buff, mysql->scramble, passwd);
2191
if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
2194
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2195
ER(CR_SERVER_LOST_EXTENDED),
2196
"sending password information",
2200
/* Read what server thinks about out new auth message report */
2201
if (cli_safe_read(mysql) == packet_error)
2203
if (mysql->net.last_errno == CR_SERVER_LOST)
2204
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2205
ER(CR_SERVER_LOST_EXTENDED),
2206
"reading final connect information",
2212
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
2215
#ifdef CHECK_LICENSE
2216
if (check_license(mysql))
2220
if (db && mysql_select_db(mysql, db))
2222
if (mysql->net.last_errno == CR_SERVER_LOST)
2223
set_mysql_extended_error(mysql, CR_SERVER_LOST, unknown_sqlstate,
2224
ER(CR_SERVER_LOST_EXTENDED),
2225
"Setting intital database",
2230
if (mysql->options.init_commands)
2232
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
2233
char **ptr= (char**)init_commands->buffer;
2234
char **end_command= ptr + init_commands->elements;
2236
my_bool reconnect=mysql->reconnect;
2239
for (; ptr < end_command; ptr++)
2242
if (mysql_real_query(mysql,*ptr, (ulong) strlen(*ptr)))
2246
if (!(res= cli_use_result(mysql)))
2248
mysql_free_result(res);
2251
mysql->reconnect=reconnect;
2254
DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
2255
reset_sigpipe(mysql);
2259
reset_sigpipe(mysql);
2260
DBUG_PRINT("error",("message: %u/%s (%s)",
2265
/* Free alloced memory */
2267
mysql_close_free(mysql);
2268
if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
2269
mysql_close_free_options(mysql);
2275
my_bool mysql_reconnect(MYSQL *mysql)
2278
DBUG_ENTER("mysql_reconnect");
2280
DBUG_PRINT("enter", ("mysql->reconnect: %d", mysql->reconnect));
2282
if (!mysql->reconnect ||
2283
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
2285
/* Allow reconnect next time */
2286
mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
2287
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
2290
mysql_init(&tmp_mysql);
2291
tmp_mysql.options= mysql->options;
2292
tmp_mysql.options.my_cnf_file= tmp_mysql.options.my_cnf_group= 0;
2294
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
2295
mysql->db, mysql->port, mysql->unix_socket,
2296
mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
2298
mysql->net.last_errno= tmp_mysql.net.last_errno;
2299
strmov(mysql->net.last_error, tmp_mysql.net.last_error);
2300
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
2303
if (mysql_set_character_set(&tmp_mysql, mysql->charset->csname))
2305
DBUG_PRINT("error", ("mysql_set_character_set() failed"));
2306
bzero((char*) &tmp_mysql.options,sizeof(tmp_mysql.options));
2307
mysql_close(&tmp_mysql);
2308
mysql->net.last_errno= tmp_mysql.net.last_errno;
2309
strmov(mysql->net.last_error, tmp_mysql.net.last_error);
2310
strmov(mysql->net.sqlstate, tmp_mysql.net.sqlstate);
2314
DBUG_PRINT("info", ("reconnect succeded"));
2315
tmp_mysql.reconnect= 1;
2316
tmp_mysql.free_me= mysql->free_me;
2318
/* Don't free options as these are now used in tmp_mysql */
2319
bzero((char*) &mysql->options,sizeof(mysql->options));
2323
net_clear(&mysql->net, 1);
2324
mysql->affected_rows= ~(my_ulonglong) 0;
2329
/**************************************************************************
2330
Set current database
2331
**************************************************************************/
2334
mysql_select_db(MYSQL *mysql, const char *db)
2337
DBUG_ENTER("mysql_select_db");
2338
DBUG_PRINT("enter",("db: '%s'",db));
2340
if ((error=simple_command(mysql,COM_INIT_DB, (const uchar*) db,
2341
(ulong) strlen(db),0)))
2343
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
2344
mysql->db=my_strdup(db,MYF(MY_WME));
2349
/*************************************************************************
2350
Send a QUIT to the server and close the connection
2351
If handle is alloced by mysql connect free it.
2352
*************************************************************************/
2354
static void mysql_close_free_options(MYSQL *mysql)
2356
DBUG_ENTER("mysql_close_free_options");
2358
my_free(mysql->options.user,MYF(MY_ALLOW_ZERO_PTR));
2359
my_free(mysql->options.host,MYF(MY_ALLOW_ZERO_PTR));
2360
my_free(mysql->options.password,MYF(MY_ALLOW_ZERO_PTR));
2361
my_free(mysql->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
2362
my_free(mysql->options.db,MYF(MY_ALLOW_ZERO_PTR));
2363
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
2364
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
2365
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
2366
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
2367
my_free(mysql->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
2368
if (mysql->options.init_commands)
2370
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
2371
char **ptr= (char**)init_commands->buffer;
2372
char **end= ptr + init_commands->elements;
2373
for (; ptr<end; ptr++)
2374
my_free(*ptr,MYF(MY_WME));
2375
delete_dynamic(init_commands);
2376
my_free((char*)init_commands,MYF(MY_WME));
2379
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
2380
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
2381
#endif /* HAVE_SMEM */
2382
bzero((char*) &mysql->options,sizeof(mysql->options));
2387
static void mysql_close_free(MYSQL *mysql)
2389
my_free((uchar*) mysql->host_info,MYF(MY_ALLOW_ZERO_PTR));
2390
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
2391
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
2392
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
2393
my_free(mysql->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
2394
mysql->info_buffer= 0;
2396
/* Clear pointers for better safety */
2397
mysql->host_info= mysql->user= mysql->passwd= mysql->db= 0;
2401
void STDCALL mysql_close(MYSQL *mysql)
2403
DBUG_ENTER("mysql_close");
2404
if (mysql) /* Some simple safety */
2406
/* If connection is still up, send a QUIT message */
2407
if (mysql->net.vio != 0)
2409
free_old_query(mysql);
2410
mysql->status=MYSQL_STATUS_READY; /* Force command */
2412
simple_command(mysql,COM_QUIT,(uchar*) 0,0,1);
2413
end_server(mysql); /* Sets mysql->net.vio= 0 */
2415
mysql_close_free_options(mysql);
2416
mysql_close_free(mysql);
2418
my_free((uchar*) mysql,MYF(0));
2424
static my_bool cli_read_query_result(MYSQL *mysql)
2430
DBUG_ENTER("cli_read_query_result");
2432
if ((length = cli_safe_read(mysql)) == packet_error)
2434
free_old_query(mysql); /* Free old result */
2435
#ifdef MYSQL_CLIENT /* Avoid warn of unused labels*/
2438
pos=(uchar*) mysql->net.read_pos;
2439
if ((field_count= net_field_length(&pos)) == 0)
2441
mysql->affected_rows= net_field_length_ll(&pos);
2442
mysql->insert_id= net_field_length_ll(&pos);
2443
DBUG_PRINT("info",("affected_rows: %lu insert_id: %lu",
2444
(ulong) mysql->affected_rows,
2445
(ulong) mysql->insert_id));
2446
if (protocol_41(mysql))
2448
mysql->server_status=uint2korr(pos); pos+=2;
2449
mysql->warning_count=uint2korr(pos); pos+=2;
2451
else if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
2453
/* MySQL 4.0 protocol */
2454
mysql->server_status=uint2korr(pos); pos+=2;
2455
mysql->warning_count= 0;
2457
DBUG_PRINT("info",("status: %u warning_count: %u",
2458
mysql->server_status, mysql->warning_count));
2459
if (pos < mysql->net.read_pos+length && net_field_length(&pos))
2460
mysql->info=(char*) pos;
2464
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
2468
if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES))
2470
set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
2474
error= handle_local_infile(mysql,(char*) pos);
2475
if ((length= cli_safe_read(mysql)) == packet_error || error)
2477
goto get_info; /* Get info packet */
2480
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
2481
mysql->server_status|= SERVER_STATUS_IN_TRANS;
2483
if (!(fields=cli_read_rows(mysql,(MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5)))
2485
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
2486
(uint) field_count,0,
2487
mysql->server_capabilities)))
2489
mysql->status= MYSQL_STATUS_GET_RESULT;
2490
mysql->field_count= (uint) field_count;
2491
DBUG_PRINT("exit",("ok"));
2497
Send the query and return so we can do something else.
2498
Needs to be followed by mysql_read_query_result() when we want to
2499
finish processing it.
2503
mysql_send_query(MYSQL* mysql, const char* query, ulong length)
2505
DBUG_ENTER("mysql_send_query");
2506
DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1));
2511
mysql_real_query(MYSQL *mysql, const char *query, ulong length)
2513
DBUG_ENTER("mysql_real_query");
2514
DBUG_PRINT("enter",("handle: 0x%lx", (long) mysql));
2515
DBUG_PRINT("query",("Query = '%-.4096s'",query));
2517
if (mysql_send_query(mysql,query,length))
2519
DBUG_RETURN((int) (*mysql->methods->read_query_result)(mysql));
2523
/**************************************************************************
2524
Alloc result struct for buffered results. All rows are read to buffer.
2525
mysql_data_seek may be used.
2526
**************************************************************************/
2528
MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql)
2531
DBUG_ENTER("mysql_store_result");
2535
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2537
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2540
mysql->status=MYSQL_STATUS_READY; /* server is ready */
2541
if (!(result=(MYSQL_RES*) my_malloc((uint) (sizeof(MYSQL_RES)+
2543
mysql->field_count),
2544
MYF(MY_WME | MY_ZEROFILL))))
2546
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
2549
result->methods= mysql->methods;
2550
result->eof=1; /* Marker for buffered */
2551
result->lengths=(ulong*) (result+1);
2553
(*mysql->methods->read_rows)(mysql,mysql->fields,mysql->field_count)))
2555
my_free((uchar*) result,MYF(0));
2558
mysql->affected_rows= result->row_count= result->data->rows;
2559
result->data_cursor= result->data->data;
2560
result->fields= mysql->fields;
2561
result->field_alloc= mysql->field_alloc;
2562
result->field_count= mysql->field_count;
2563
/* The rest of result members is bzeroed in malloc */
2564
mysql->fields=0; /* fields is now in result */
2565
clear_alloc_root(&mysql->field_alloc);
2566
/* just in case this was mistakenly called after mysql_stmt_execute() */
2567
mysql->unbuffered_fetch_owner= 0;
2568
DBUG_RETURN(result); /* Data fetched */
2572
/**************************************************************************
2573
Alloc struct for use with unbuffered reads. Data is fetched by domand
2574
when calling to mysql_fetch_row.
2575
mysql_data_seek is a noop.
2577
No other queries may be specified with the same MYSQL handle.
2578
There shouldn't be much processing per row because mysql server shouldn't
2579
have to wait for the client (and will not wait more than 30 sec/packet).
2580
**************************************************************************/
2582
static MYSQL_RES * cli_use_result(MYSQL *mysql)
2585
DBUG_ENTER("cli_use_result");
2589
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2591
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2594
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result)+
2595
sizeof(ulong)*mysql->field_count,
2596
MYF(MY_WME | MY_ZEROFILL))))
2598
result->lengths=(ulong*) (result+1);
2599
result->methods= mysql->methods;
2600
if (!(result->row=(MYSQL_ROW)
2601
my_malloc(sizeof(result->row[0])*(mysql->field_count+1), MYF(MY_WME))))
2602
{ /* Ptrs: to one row */
2603
my_free((uchar*) result,MYF(0));
2606
result->fields= mysql->fields;
2607
result->field_alloc= mysql->field_alloc;
2608
result->field_count= mysql->field_count;
2609
result->current_field=0;
2610
result->handle= mysql;
2611
result->current_row= 0;
2612
mysql->fields=0; /* fields is now in result */
2613
clear_alloc_root(&mysql->field_alloc);
2614
mysql->status=MYSQL_STATUS_USE_RESULT;
2615
mysql->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
2616
DBUG_RETURN(result); /* Data is read to be fetched */
432
2621
Return next row of the query results
433
2622
**************************************************************************/
436
drizzle_fetch_row(DRIZZLE_RES *res)
2625
mysql_fetch_row(MYSQL_RES *res)
2627
DBUG_ENTER("mysql_fetch_row");
439
{ /* Unbufferred fetch */
2629
{ /* 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);
2632
MYSQL *mysql= res->handle;
2633
if (mysql->status != MYSQL_STATUS_USE_RESULT)
2635
set_mysql_error(mysql,
2636
res->unbuffered_fetch_cancelled ?
2637
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
2640
else if (!(read_one_row(mysql, res->field_count, res->row, res->lengths)))
2643
DBUG_RETURN(res->current_row=res->row);
2645
DBUG_PRINT("info",("end of data"));
456
drizzle->status=DRIZZLE_STATUS_READY;
2647
mysql->status=MYSQL_STATUS_READY;
458
2649
Reset only if owner points to us: there is a chance that somebody
459
started new query after drizzle_stmt_close():
2650
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 */
2652
if (mysql->unbuffered_fetch_owner == &res->unbuffered_fetch_cancelled)
2653
mysql->unbuffered_fetch_owner= 0;
2654
/* Don't clear handle in mysql_free_result */
466
return((DRIZZLE_ROW) NULL);
2657
DBUG_RETURN((MYSQL_ROW) NULL);
470
2661
if (!res->data_cursor)
472
return(res->current_row=(DRIZZLE_ROW) NULL);
2663
DBUG_PRINT("info",("end of data"));
2664
DBUG_RETURN(res->current_row=(MYSQL_ROW) NULL);
474
2666
tmp = res->data_cursor->data;
475
2667
res->data_cursor = res->data_cursor->next;
476
return(res->current_row=tmp);
2668
DBUG_RETURN(res->current_row=tmp);
481
2673
/**************************************************************************
482
2674
Get column lengths of the current row
483
If one uses drizzle_use_result, res->lengths contains the length information,
2675
If one uses mysql_use_result, res->lengths contains the length information,
484
2676
else the lengths are calculated from the offset between pointers.
485
2677
**************************************************************************/
488
drizzle_fetch_lengths(DRIZZLE_RES *res)
2680
mysql_fetch_lengths(MYSQL_RES *res)
492
2684
if (!(column=res->current_row))
493
return 0; /* Something is wrong */
2685
return 0; /* Something is wrong */
495
2687
(*res->methods->fetch_lengths)(res->lengths, column, res->field_count);
496
2688
return res->lengths;
501
drizzle_options(DRIZZLE *drizzle,enum drizzle_option option, const void *arg)
2693
mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
2695
DBUG_ENTER("mysql_option");
2696
DBUG_PRINT("enter",("option: %d",(int) option));
503
2697
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;
2698
case MYSQL_OPT_CONNECT_TIMEOUT:
2699
mysql->options.connect_timeout= *(uint*) arg;
2701
case MYSQL_OPT_READ_TIMEOUT:
2702
mysql->options.read_timeout= *(uint*) arg;
2704
case MYSQL_OPT_WRITE_TIMEOUT:
2705
mysql->options.write_timeout= *(uint*) arg;
2707
case MYSQL_OPT_COMPRESS:
2708
mysql->options.compress= 1; /* Remember for connect */
2709
mysql->options.client_flag|= CLIENT_COMPRESS;
2711
case MYSQL_OPT_NAMED_PIPE: /* This option is depricated */
2712
mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */
2714
case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/
2715
if (!arg || test(*(uint*) arg))
2716
mysql->options.client_flag|= CLIENT_LOCAL_FILES;
2718
mysql->options.client_flag&= ~CLIENT_LOCAL_FILES;
2720
case MYSQL_INIT_COMMAND:
2721
add_init_command(&mysql->options,arg);
2723
case MYSQL_READ_DEFAULT_FILE:
2724
my_free(mysql->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
2725
mysql->options.my_cnf_file=my_strdup(arg,MYF(MY_WME));
2727
case MYSQL_READ_DEFAULT_GROUP:
2728
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
2729
mysql->options.my_cnf_group=my_strdup(arg,MYF(MY_WME));
2731
case MYSQL_SET_CHARSET_DIR:
2732
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
2733
mysql->options.charset_dir=my_strdup(arg,MYF(MY_WME));
2735
case MYSQL_SET_CHARSET_NAME:
2736
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
2737
mysql->options.charset_name=my_strdup(arg,MYF(MY_WME));
2739
case MYSQL_OPT_PROTOCOL:
2740
mysql->options.protocol= *(uint*) arg;
2742
case MYSQL_SHARED_MEMORY_BASE_NAME:
2744
if (mysql->options.shared_memory_base_name != def_shared_memory_base_name)
2745
my_free(mysql->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
2746
mysql->options.shared_memory_base_name=my_strdup(arg,MYF(MY_WME));
2749
case MYSQL_OPT_USE_REMOTE_CONNECTION:
2750
case MYSQL_OPT_USE_EMBEDDED_CONNECTION:
2751
case MYSQL_OPT_GUESS_CONNECTION:
2752
mysql->options.methods_to_use= option;
2754
case MYSQL_SET_CLIENT_IP:
2755
mysql->options.client_ip= my_strdup(arg, MYF(MY_WME));
2757
case MYSQL_SECURE_AUTH:
2758
mysql->options.secure_auth= *(my_bool *) arg;
2760
case MYSQL_REPORT_DATA_TRUNCATION:
2761
mysql->options.report_data_truncation= test(*(my_bool *) arg);
2763
case MYSQL_OPT_RECONNECT:
2764
mysql->reconnect= *(my_bool *) arg;
2766
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
2767
if (*(my_bool*) arg)
2768
mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
2770
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
564
2779
/****************************************************************************
565
Functions to get information from the DRIZZLE structure
2780
Functions to get information from the MySQL structure
566
2781
These are functions to make shared libraries more usable.
567
2782
****************************************************************************/
570
uint64_t drizzle_num_rows(const DRIZZLE_RES *res)
2785
my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res)
572
2787
return res->row_count;
575
unsigned int drizzle_num_fields(const DRIZZLE_RES *res)
2790
unsigned int STDCALL mysql_num_fields(MYSQL_RES *res)
577
2792
return res->field_count;
2795
uint STDCALL mysql_errno(MYSQL *mysql)
2797
return mysql ? mysql->net.last_errno : mysql_server_last_errno;
2801
const char * STDCALL mysql_error(MYSQL *mysql)
2803
return mysql ? mysql->net.last_error : mysql_server_last_error;
582
2808
Get version number for server in a form easy to test on
585
drizzle_get_server_version()
2811
mysql_get_server_version()
589
2815
4.1.0-alfa -> 40100
592
2818
We will ensure that a newer server always has a bigger number.