76
77
#include <sys/un.h>
81
#include <drizzled/gettext.h>
82
#include "local_infile.h"
91
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
92
struct passwd *getpwuid(uid_t);
80
#define SOCKET_ERROR -1
82
#define CONNECT_TIMEOUT 0
84
#include "client_settings.h"
85
#include <sql_common.h>
88
char *drizzle_unix_port= 0;
89
const char *unknown_sqlstate= "HY000";
90
const char *not_error_sqlstate= "00000";
91
const char *cant_connect_sqlstate= "08001";
93
static bool drizzle_client_init= false;
94
static bool org_my_init_done= false;
96
static void drizzle_close_free_options(DRIZZLE *drizzle);
97
static void drizzle_close_free(DRIZZLE *drizzle);
99
static int wait_for_data(my_socket fd, uint timeout);
101
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
103
/* Server error code and message */
104
unsigned int drizzle_server_last_errno;
105
char drizzle_server_last_error[MYSQL_ERRMSG_SIZE];
107
/****************************************************************************
108
A modified version of connect(). my_connect() allows you to specify
109
a timeout value, in seconds, that we should wait until we
110
derermine we can't connect to a particular host. If timeout is 0,
111
my_connect() will behave exactly like connect().
113
Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
114
*****************************************************************************/
116
int my_connect(my_socket fd, const struct sockaddr *name, uint namelen,
119
int flags, res, s_err;
122
If they passed us a timeout of zero, we should behave
123
exactly like the normal connect() call does.
127
return connect(fd, (struct sockaddr*) name, namelen);
129
flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */
131
fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */
134
res= connect(fd, (struct sockaddr*) name, namelen);
135
s_err= errno; /* Save the error... */
136
fcntl(fd, F_SETFL, flags);
137
if ((res != 0) && (s_err != EINPROGRESS))
139
errno= s_err; /* Restore it */
142
if (res == 0) /* Connected quickly! */
144
return wait_for_data(fd, timeout);
149
Wait up to timeout seconds for a connection to be established.
151
We prefer to do this with poll() as there is no limitations with this.
152
If not, we will use select()
155
static int wait_for_data(my_socket fd, uint timeout)
162
ufds.events= POLLIN | POLLPRI;
163
if (!(res= poll(&ufds, 1, (int) timeout*1000)))
168
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
172
SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint);
175
time_t start_time, now_time;
178
if (fd >= FD_SETSIZE) /* Check if wrong error */
179
return 0; /* Can't use timeout */
182
Our connection is "in progress." We can use the select() call to wait
183
up to a specified period of time for the connection to suceed.
184
If select() returns 0 (after waiting howevermany seconds), our socket
185
never became writable (host is probably unreachable.) Otherwise, if
186
select() returns 1, then one of two conditions exist:
188
1. An error occured. We use getsockopt() to check for this.
189
2. The connection was set up sucessfully: getsockopt() will
190
return 0 as an error.
192
Thanks goes to Andrew Gierth <andrew@erlenstar.demon.co.uk>
193
who posted this method of timing out a connect() in
194
comp.unix.programmer on August 15th, 1997.
200
select could be interrupted by a signal, and if it is,
201
the timeout should be adjusted and the select restarted
202
to work around OSes that don't restart select and
203
implementations of select that don't adjust tv upon
204
failure to reflect the time remaining
206
start_time= my_time(0);
209
tv.tv_sec = (long) timeout;
212
if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
215
if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0)
218
if (res == 0) /* timeout */
220
now_time= my_time(0);
221
timeout-= (uint) (now_time - start_time);
222
if (errno != EINTR || (int) timeout <= 0)
227
select() returned something more interesting than zero, let's
228
see if we have any errors. If the next two statements pass,
229
we've got an open socket!
233
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0)
237
{ /* getsockopt could succeed */
239
return(-1); /* but return an error... */
242
#endif /* HAVE_POLL */
246
Set the internal error message to DRIZZLE handler
248
@param drizzle connection handle (client side)
249
@param errcode CR_ error code, passed to ER macro to get
251
@parma sqlstate SQL standard sqlstate
254
void set_drizzle_error(DRIZZLE *drizzle, int errcode, const char *sqlstate)
257
assert(drizzle != 0);
262
net->last_errno= errcode;
263
strmov(net->last_error, ER(errcode));
264
strmov(net->sqlstate, sqlstate);
268
drizzle_server_last_errno= errcode;
269
strmov(drizzle_server_last_error, ER(errcode));
275
Clear possible error state of struct NET
277
@param net clear the state of the argument
280
void net_clear_error(NET *net)
283
net->last_error[0]= '\0';
284
strmov(net->sqlstate, not_error_sqlstate);
288
Set an error message on the client.
290
@param drizzle connection handle
291
@param errcode CR_* errcode, for client errors
292
@param sqlstate SQL standard sql state, unknown_sqlstate for the
293
majority of client errors.
294
@param format error message template, in sprintf format
295
@param ... variable number of arguments
298
static void set_drizzle_extended_error(DRIZZLE *drizzle, int errcode,
299
const char *sqlstate,
300
const char *format, ...)
304
assert(drizzle != 0);
307
net->last_errno= errcode;
308
va_start(args, format);
309
vsnprintf(net->last_error, sizeof(net->last_error)-1,
312
strmov(net->sqlstate, sqlstate);
98
317
/*****************************************************************************
99
318
Read a packet from server. Give error message if socket was down
270
539
free_rows(result->data);
271
/* TODO: free result->fields */
541
free_root(&result->field_alloc,MYF(0));
273
free((unsigned char*) result->row);
274
free((unsigned char*) result);
543
my_free((uchar*) result->row,MYF(0));
544
my_free((uchar*) result,MYF(0));
549
/****************************************************************************
550
Get options from my.cnf
551
****************************************************************************/
553
static const char *default_options[]=
555
"port","socket","compress","password","pipe", "timeout", "user",
556
"init-command", "host", "database", "return-found-rows",
557
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
558
"character-sets-dir", "default-character-set", "interactive-timeout",
559
"connect-timeout", "local-infile", "disable-local-infile",
560
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
561
"multi-results", "multi-statements", "multi-queries", "secure-auth",
562
"report-data-truncation",
566
static TYPELIB option_types={array_elements(default_options)-1,
567
"options",default_options, NULL};
569
const char *sql_protocol_names_lib[] =
570
{ "TCP", "SOCKET", "PIPE", "MEMORY", NullS };
571
TYPELIB sql_protocol_typelib = {array_elements(sql_protocol_names_lib)-1,"",
572
sql_protocol_names_lib, NULL};
574
static int add_init_command(struct st_drizzle_options *options, const char *cmd)
578
if (!options->init_commands)
580
options->init_commands= (DYNAMIC_ARRAY*)my_malloc(sizeof(DYNAMIC_ARRAY),
582
init_dynamic_array(options->init_commands,sizeof(char*),0,5 CALLER_INFO);
585
if (!(tmp= my_strdup(cmd,MYF(MY_WME))) ||
586
insert_dynamic(options->init_commands, (uchar*)&tmp))
588
my_free(tmp, MYF(MY_ALLOW_ZERO_PTR));
595
void drizzle_read_default_options(struct st_drizzle_options *options,
596
const char *filename,const char *group)
599
char *argv_buff[1],**argv;
600
const char *groups[3];
602
argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
603
groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
605
load_defaults(filename, groups, &argc, &argv);
606
if (argc != 1) /* If some default option */
611
if (option[0][0] == '-' && option[0][1] == '-')
613
char *end=strcend(*option,'=');
618
*end=0; /* Remove '=' */
620
/* Change all '_' in variable name to '-' */
621
for (end= *option ; *(end= strcend(end,'_')) ; )
623
switch (find_type(*option+2,&option_types,2)) {
626
options->port=atoi(opt_arg);
631
my_free(options->unix_socket,MYF(MY_ALLOW_ZERO_PTR));
632
options->unix_socket=my_strdup(opt_arg,MYF(MY_WME));
635
case 3: /* compress */
637
options->client_flag|= CLIENT_COMPRESS;
639
case 4: /* password */
642
my_free(options->password,MYF(MY_ALLOW_ZERO_PTR));
643
options->password=my_strdup(opt_arg,MYF(MY_WME));
647
options->protocol = DRIZZLE_PROTOCOL_PIPE;
648
case 20: /* connect_timeout */
649
case 6: /* timeout */
651
options->connect_timeout=atoi(opt_arg);
656
my_free(options->user,MYF(MY_ALLOW_ZERO_PTR));
657
options->user=my_strdup(opt_arg,MYF(MY_WME));
660
case 8: /* init-command */
661
add_init_command(options,opt_arg);
666
my_free(options->host,MYF(MY_ALLOW_ZERO_PTR));
667
options->host=my_strdup(opt_arg,MYF(MY_WME));
670
case 10: /* database */
673
my_free(options->db,MYF(MY_ALLOW_ZERO_PTR));
674
options->db=my_strdup(opt_arg,MYF(MY_WME));
677
case 12: /* return-found-rows */
678
options->client_flag|=CLIENT_FOUND_ROWS;
680
case 13: /* Ignore SSL options */
686
case 17: /* charset-lib */
687
my_free(options->charset_dir,MYF(MY_ALLOW_ZERO_PTR));
688
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
691
my_free(options->charset_name,MYF(MY_ALLOW_ZERO_PTR));
692
options->charset_name = my_strdup(opt_arg, MYF(MY_WME));
694
case 19: /* Interactive-timeout */
695
options->client_flag|= CLIENT_INTERACTIVE;
698
if (!opt_arg || atoi(opt_arg) != 0)
699
options->client_flag|= CLIENT_LOCAL_FILES;
701
options->client_flag&= ~CLIENT_LOCAL_FILES;
704
options->client_flag&= ~CLIENT_LOCAL_FILES;
706
case 24: /* max-allowed-packet */
708
options->max_allowed_packet= atoi(opt_arg);
710
case 25: /* protocol */
711
if ((options->protocol= find_type(opt_arg,
712
&sql_protocol_typelib,0)) <= 0)
714
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
718
case 26: /* shared_memory_base_name */
720
if (options->shared_memory_base_name != def_shared_memory_base_name)
721
my_free(options->shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
722
options->shared_memory_base_name=my_strdup(opt_arg,MYF(MY_WME));
725
case 27: /* multi-results */
726
options->client_flag|= CLIENT_MULTI_RESULTS;
728
case 28: /* multi-statements */
729
case 29: /* multi-queries */
730
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
732
case 30: /* secure-auth */
733
options->secure_auth= true;
735
case 31: /* report-data-truncation */
736
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
749
/**************************************************************************
750
Get column lengths of the current row
751
If one uses drizzle_use_result, res->lengths contains the length information,
752
else the lengths are calculated from the offset between pointers.
753
**************************************************************************/
755
static void cli_fetch_lengths(uint32_t *to, DRIZZLE_ROW column, uint32_t field_count)
757
uint32_t *prev_length;
761
prev_length=0; /* Keep gcc happy */
762
for (end=column + field_count + 1 ; column != end ; column++, to++)
769
if (start) /* Found end of prev string */
770
*prev_length= (ulong) (*column-start-1);
776
/***************************************************************************
777
Change field rows to field structs
778
***************************************************************************/
781
unpack_fields(DRIZZLE_DATA *data,MEM_ROOT *alloc,uint fields,
782
my_bool default_value, uint server_capabilities)
785
DRIZZLE_FIELD *field,*result;
786
uint32_t lengths[9]; /* Max of fields */
788
field= result= (DRIZZLE_FIELD*) alloc_root(alloc,
789
(uint) sizeof(*field)*fields);
792
free_rows(data); /* Free old data */
795
bzero((char*) field, (uint) sizeof(DRIZZLE_FIELD)*fields);
796
if (server_capabilities & CLIENT_PROTOCOL_41)
798
/* server is 4.1, and returns the new field result format */
799
for (row=data->data; row ; row = row->next,field++)
802
/* fields count may be wrong */
803
assert((uint) (field - result) < fields);
804
cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
805
field->catalog= strmake_root(alloc,(char*) row->data[0], lengths[0]);
806
field->db= strmake_root(alloc,(char*) row->data[1], lengths[1]);
807
field->table= strmake_root(alloc,(char*) row->data[2], lengths[2]);
808
field->org_table= strmake_root(alloc,(char*) row->data[3], lengths[3]);
809
field->name= strmake_root(alloc,(char*) row->data[4], lengths[4]);
810
field->org_name= strmake_root(alloc,(char*) row->data[5], lengths[5]);
812
field->catalog_length= lengths[0];
813
field->db_length= lengths[1];
814
field->table_length= lengths[2];
815
field->org_table_length= lengths[3];
816
field->name_length= lengths[4];
817
field->org_name_length= lengths[5];
819
/* Unpack fixed length parts */
820
pos= (uchar*) row->data[6];
821
field->charsetnr= uint2korr(pos);
822
field->length= (uint) uint4korr(pos+2);
823
field->type= (enum enum_field_types) pos[6];
824
field->flags= uint2korr(pos+7);
825
field->decimals= (uint) pos[9];
827
if (INTERNAL_NUM_FIELD(field))
828
field->flags|= NUM_FLAG;
829
if (default_value && row->data[7])
831
field->def=strmake_root(alloc,(char*) row->data[7], lengths[7]);
832
field->def_length= lengths[7];
836
field->max_length= 0;
839
#ifndef DELETE_SUPPORT_OF_4_0_PROTOCOL
842
/* old protocol, for backward compatibility */
843
for (row=data->data; row ; row = row->next,field++)
845
cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
846
field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
847
field->name= strdup_root(alloc,(char*) row->data[1]);
848
field->length= (uint) uint3korr(row->data[2]);
849
field->type= (enum enum_field_types) (uchar) row->data[3][0];
851
field->catalog=(char*) "";
852
field->db= (char*) "";
853
field->catalog_length= 0;
855
field->org_table_length= field->table_length= lengths[0];
856
field->name_length= lengths[1];
858
if (server_capabilities & CLIENT_LONG_FLAG)
860
field->flags= uint2korr(row->data[4]);
861
field->decimals=(uint) (uchar) row->data[4][2];
865
field->flags= (uint) (uchar) row->data[4][0];
866
field->decimals=(uint) (uchar) row->data[4][1];
868
if (INTERNAL_NUM_FIELD(field))
869
field->flags|= NUM_FLAG;
870
if (default_value && row->data[5])
872
field->def=strdup_root(alloc,(char*) row->data[5]);
873
field->def_length= lengths[5];
877
field->max_length= 0;
880
#endif /* DELETE_SUPPORT_OF_4_0_PROTOCOL */
881
free_rows(data); /* Free old data */
281
885
/* Read all rows (fields or data) from server */
283
DRIZZLE_DATA *cli_read_rows(DRIZZLE *drizzle, DRIZZLE_FIELD *DRIZZLE_FIELDs, uint32_t fields)
887
DRIZZLE_DATA *cli_read_rows(DRIZZLE *drizzle,DRIZZLE_FIELD *DRIZZLE_FIELDs,
289
894
char *to, *end_to;
290
895
DRIZZLE_DATA *result;
291
896
DRIZZLE_ROWS **prev_ptr,*cur;
1035
/****************************************************************************
1036
Init DRIZZLE structure or allocate one
1037
****************************************************************************/
1040
drizzle_create(DRIZZLE *ptr)
1043
if (!drizzle_client_init)
1045
drizzle_client_init=true;
1046
org_my_init_done=my_init_done;
1048
/* Will init threads */
1056
drizzle_port = MYSQL_PORT;
1058
struct servent *serv_ptr;
1062
if builder specifically requested a default port, use that
1063
(even if it coincides with our factory default).
1064
only if they didn't do we check /etc/services (and, failing
1065
on that, fall back to the factory default of 4427).
1066
either default can be overridden by the environment variable
1067
MYSQL_TCP_PORT, which in turn can be overridden with command
1071
#if MYSQL_PORT_DEFAULT == 0
1072
if ((serv_ptr = getservbyname("drizzle", "tcp")))
1073
drizzle_port = (uint) ntohs((ushort) serv_ptr->s_port);
1075
if ((env = getenv("DRIZZLE_TCP_PORT")))
1076
drizzle_port =(uint) atoi(env);
1079
if (!drizzle_unix_port)
1082
drizzle_unix_port = (char*) MYSQL_UNIX_ADDR;
1083
if ((env = getenv("DRIZZLE_UNIX_PORT")))
1084
drizzle_unix_port = env;
1086
#if defined(SIGPIPE)
1087
(void) signal(SIGPIPE, SIG_IGN);
1091
/* Init if new thread */
1092
if (my_thread_init())
1097
ptr= (DRIZZLE *) malloc(sizeof(DRIZZLE));
1101
set_drizzle_error(NULL, CR_OUT_OF_MEMORY, unknown_sqlstate);
1104
memset(ptr, 0, sizeof(DRIZZLE));
1109
memset(ptr, 0, sizeof(DRIZZLE));
1112
ptr->options.connect_timeout= CONNECT_TIMEOUT;
1113
ptr->charset=default_client_charset_info;
1114
strcpy(ptr->net.sqlstate, not_error_sqlstate);
1117
Only enable LOAD DATA INFILE by default if configured with
1118
--enable-local-infile
1121
#if defined(ENABLED_LOCAL_INFILE) && !defined(DRIZZLE_SERVER)
1122
ptr->options.client_flag|= CLIENT_LOCAL_FILES;
1126
ptr->options.shared_memory_base_name= (char*) def_shared_memory_base_name;
1129
ptr->options.methods_to_use= DRIZZLE_OPT_GUESS_CONNECTION;
1130
ptr->options.report_data_truncation= true; /* default */
1133
By default we don't reconnect because it could silently corrupt data (after
1134
reconnection you potentially lose table locks, user variables, session
1135
variables (transactions but they are specifically dealt with in
1136
drizzle_reconnect()).
1137
This is a change: < 5.0.3 drizzle->reconnect was set to 1 by default.
1138
How this change impacts existing apps:
1139
- existing apps which relyed on the default will see a behaviour change;
1140
they will have to set reconnect=1 after drizzle_connect().
1141
- existing apps which explicitely asked for reconnection (the only way they
1142
could do it was by setting drizzle.reconnect to 1 after drizzle_connect())
1143
will not see a behaviour change.
1144
- existing apps which explicitely asked for no reconnection
1145
(drizzle.reconnect=0) will not see a behaviour change.
1154
Free all memory and resources used by the client library
1157
When calling this there should not be any other threads using
1160
To make things simpler when used with windows dll's (which calls this
1161
function automaticly), it's safe to call this function multiple times.
1165
void STDCALL drizzle_server_end()
1167
if (!drizzle_client_init)
1170
finish_client_errs();
1173
/* If library called my_init(), free memory allocated by it */
1174
if (!org_my_init_done)
1181
drizzle_thread_end();
1184
drizzle_client_init= org_my_init_done= 0;
1185
#ifdef EMBEDDED_SERVER
1188
fclose(stderror_file);
1196
Fill in SSL part of DRIZZLE structure and set 'use_ssl' flag.
1197
NB! Errors are not reported until you do drizzle_connect.
1200
#define strdup_if_not_null(A) (A) == 0 ? 0 : my_strdup((A),MYF(MY_WME))
1203
Note that the drizzle argument must be initialized with drizzle_init()
1204
before calling drizzle_connect !
1207
static bool cli_read_query_result(DRIZZLE *drizzle);
1208
static DRIZZLE_RES *cli_use_result(DRIZZLE *drizzle);
1210
static DRIZZLE_METHODS client_methods=
1212
cli_read_query_result, /* read_query_result */
1213
cli_advanced_command, /* advanced_command */
1214
cli_read_rows, /* read_rows */
1215
cli_use_result, /* use_result */
1216
cli_fetch_lengths, /* fetch_lengths */
1217
cli_flush_use_result, /* flush_use_result */
1218
#ifndef MYSQL_SERVER
1219
cli_list_fields, /* list_fields */
1220
cli_unbuffered_fetch, /* unbuffered_fetch */
1221
cli_read_statistics, /* read_statistics */
1222
cli_read_query_result, /* next_result */
1223
cli_read_change_user_result, /* read_change_user_result */
1230
int drizzle_init_character_set(DRIZZLE *drizzle)
1232
const char *default_collation_name;
1234
/* Set character set */
1235
if (!drizzle->options.charset_name)
1237
default_collation_name= MYSQL_DEFAULT_COLLATION_NAME;
1238
if (!(drizzle->options.charset_name=
1239
my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
1243
default_collation_name= NULL;
1246
const char *save= charsets_dir;
1247
if (drizzle->options.charset_dir)
1248
charsets_dir=drizzle->options.charset_dir;
1249
drizzle->charset=get_charset_by_csname(drizzle->options.charset_name,
1250
MY_CS_PRIMARY, MYF(MY_WME));
1251
if (drizzle->charset && default_collation_name)
1253
CHARSET_INFO *collation;
1255
get_charset_by_name(default_collation_name, MYF(MY_WME))))
1257
if (!my_charset_same(drizzle->charset, collation))
1259
my_printf_error(ER_UNKNOWN_ERROR,
1260
"COLLATION %s is not valid for CHARACTER SET %s",
1262
default_collation_name, drizzle->options.charset_name);
1263
drizzle->charset= NULL;
1267
drizzle->charset= collation;
1271
drizzle->charset= NULL;
1276
if (!drizzle->charset)
1278
if (drizzle->options.charset_dir)
1279
set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
1280
ER(CR_CANT_READ_CHARSET),
1281
drizzle->options.charset_name,
1282
drizzle->options.charset_dir);
1285
char cs_dir_name[FN_REFLEN];
1286
get_charsets_dir(cs_dir_name);
1287
set_drizzle_extended_error(drizzle, CR_CANT_READ_CHARSET, unknown_sqlstate,
1288
ER(CR_CANT_READ_CHARSET),
1289
drizzle->options.charset_name,
1300
CLI_DRIZZLE_CONNECT(DRIZZLE *drizzle,const char *host, const char *user,
1301
const char *passwd, const char *db,
1302
uint32_t port, const char *unix_socket, uint32_t client_flag)
1304
char buff[NAME_LEN+USERNAME_LENGTH+100];
1305
char *end,*host_info=NULL;
1306
uint32_t pkt_length;
1307
NET *net= &drizzle->net;
1308
struct sockaddr_un UNIXaddr;
1309
init_sigpipe_variables
1311
/* Don't give sigpipe errors if the client doesn't want them */
1312
set_sigpipe(drizzle);
1313
drizzle->methods= &client_methods;
1314
net->vio = 0; /* If something goes wrong */
1315
drizzle->client_flag=0; /* For handshake */
1317
/* use default options */
1318
if (drizzle->options.my_cnf_file || drizzle->options.my_cnf_group)
1320
drizzle_read_default_options(&drizzle->options,
1321
(drizzle->options.my_cnf_file ?
1322
drizzle->options.my_cnf_file : "my"),
1323
drizzle->options.my_cnf_group);
1324
my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1325
my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1326
drizzle->options.my_cnf_file=drizzle->options.my_cnf_group=0;
1329
/* Some empty-string-tests are done because of ODBC */
1330
if (!host || !host[0])
1331
host=drizzle->options.host;
1332
if (!user || !user[0])
1334
user=drizzle->options.user;
1340
passwd=drizzle->options.password;
1345
db=drizzle->options.db;
1347
port=drizzle->options.port;
1349
unix_socket=drizzle->options.unix_socket;
1351
drizzle->server_status=SERVER_STATUS_AUTOCOMMIT;
1354
Part 0: Grab a socket and connect it to the server
1356
#if defined(HAVE_SMEM)
1357
if ((!drizzle->options.protocol ||
1358
drizzle->options.protocol == DRIZZLE_PROTOCOL_MEMORY) &&
1359
(!host || !strcmp(host,LOCAL_HOST)))
1361
if ((create_shared_memory(drizzle,net, drizzle->options.connect_timeout)) ==
1362
INVALID_HANDLE_VALUE)
1364
if (drizzle->options.protocol == DRIZZLE_PROTOCOL_MEMORY)
1368
Try also with PIPE or TCP/IP. Clear the error from
1369
create_shared_memory().
1372
net_clear_error(net);
1376
drizzle->options.protocol=DRIZZLE_PROTOCOL_MEMORY;
1378
host=drizzle->options.shared_memory_base_name;
1379
snprintf(host_info=buff, sizeof(buff)-1,
1380
ER(CR_SHARED_MEMORY_CONNECTION), host);
1383
#endif /* HAVE_SMEM */
1385
(!drizzle->options.protocol ||
1386
drizzle->options.protocol == DRIZZLE_PROTOCOL_SOCKET) &&
1387
(unix_socket || drizzle_unix_port) &&
1388
(!host || !strcmp(host,LOCAL_HOST)))
1390
my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0);
1391
if (sock == SOCKET_ERROR)
1393
set_drizzle_extended_error(drizzle, CR_SOCKET_CREATE_ERROR,
1395
ER(CR_SOCKET_CREATE_ERROR),
1400
net->vio= vio_new(sock, VIO_TYPE_SOCKET,
1401
VIO_LOCALHOST | VIO_BUFFERED_READ);
1404
set_drizzle_error(drizzle, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1411
unix_socket= drizzle_unix_port;
1412
host_info= (char*) ER(CR_LOCALHOST_CONNECTION);
1414
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
1415
UNIXaddr.sun_family= AF_UNIX;
1416
strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);
1418
if (my_connect(sock, (struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
1419
drizzle->options.connect_timeout))
1421
set_drizzle_extended_error(drizzle, CR_CONNECTION_ERROR,
1423
ER(CR_CONNECTION_ERROR),
1424
unix_socket, socket_errno);
1425
vio_delete(net->vio);
1429
drizzle->options.protocol=DRIZZLE_PROTOCOL_SOCKET;
1432
(!drizzle->options.protocol ||
1433
drizzle->options.protocol == DRIZZLE_PROTOCOL_TCP))
1435
struct addrinfo *res_lst, hints, *t_res;
1437
char port_buf[NI_MAXSERV];
1439
unix_socket=0; /* This is not used */
1447
snprintf(host_info=buff, sizeof(buff)-1, ER(CR_TCP_CONNECTION), host);
1449
memset(&hints, 0, sizeof(hints));
1450
hints.ai_socktype= SOCK_STREAM;
1451
hints.ai_protocol= IPPROTO_TCP;
1452
hints.ai_family= AF_UNSPEC;
1454
snprintf(port_buf, NI_MAXSERV, "%d", port);
1455
gai_errno= getaddrinfo(host, port_buf, &hints, &res_lst);
1459
set_drizzle_extended_error(drizzle, CR_UNKNOWN_HOST, unknown_sqlstate,
1460
ER(CR_UNKNOWN_HOST), host, errno);
1465
/* We only look at the first item (something to think about changing in the future) */
1468
my_socket sock= socket(t_res->ai_family, t_res->ai_socktype,
1469
t_res->ai_protocol);
1470
if (sock == SOCKET_ERROR)
1472
set_drizzle_extended_error(drizzle, CR_IPSOCK_ERROR, unknown_sqlstate,
1473
ER(CR_IPSOCK_ERROR), socket_errno);
1474
freeaddrinfo(res_lst);
1478
net->vio= vio_new(sock, VIO_TYPE_TCPIP, VIO_BUFFERED_READ);
1481
set_drizzle_error(drizzle, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1483
freeaddrinfo(res_lst);
1487
if (my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
1488
drizzle->options.connect_timeout))
1490
set_drizzle_extended_error(drizzle, CR_CONN_HOST_ERROR, unknown_sqlstate,
1491
ER(CR_CONN_HOST_ERROR), host, socket_errno);
1492
vio_delete(net->vio);
1494
freeaddrinfo(res_lst);
1499
freeaddrinfo(res_lst);
1504
set_drizzle_error(drizzle, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate);
1508
if (my_net_init(net, net->vio))
1510
vio_delete(net->vio);
1512
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1515
vio_keepalive(net->vio,true);
1517
/* If user set read_timeout, let it override the default */
1518
if (drizzle->options.read_timeout)
1519
my_net_set_read_timeout(net, drizzle->options.read_timeout);
1521
/* If user set write_timeout, let it override the default */
1522
if (drizzle->options.write_timeout)
1523
my_net_set_write_timeout(net, drizzle->options.write_timeout);
1525
if (drizzle->options.max_allowed_packet)
1526
net->max_packet_size= drizzle->options.max_allowed_packet;
1528
/* Get version info */
1529
drizzle->protocol_version= PROTOCOL_VERSION; /* Assume this */
1530
if (drizzle->options.connect_timeout &&
1531
vio_poll_read(net->vio, drizzle->options.connect_timeout))
1533
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1534
ER(CR_SERVER_LOST_EXTENDED),
1535
"waiting for initial communication packet",
1541
Part 1: Connection established, read and parse first packet
1544
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
1546
if (drizzle->net.last_errno == CR_SERVER_LOST)
1547
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1548
ER(CR_SERVER_LOST_EXTENDED),
1549
"reading initial communication packet",
1553
/* Check if version of protocol matches current one */
1555
drizzle->protocol_version= net->read_pos[0];
1556
if (drizzle->protocol_version != PROTOCOL_VERSION)
1558
set_drizzle_extended_error(drizzle, CR_VERSION_ERROR, unknown_sqlstate,
1559
ER(CR_VERSION_ERROR), drizzle->protocol_version,
1563
end=strend((char*) net->read_pos+1);
1564
drizzle->thread_id=uint4korr(end+1);
1567
Scramble is split into two parts because old clients does not understand
1568
long scrambles; here goes the first part.
1570
strmake(drizzle->scramble, end, SCRAMBLE_LENGTH_323);
1571
end+= SCRAMBLE_LENGTH_323+1;
1573
if (pkt_length >= (uint) (end+1 - (char*) net->read_pos))
1574
drizzle->server_capabilities=uint2korr(end);
1575
if (pkt_length >= (uint) (end+18 - (char*) net->read_pos))
1577
/* New protocol with 16 bytes to describe server characteristics */
1578
drizzle->server_language=end[2];
1579
drizzle->server_status=uint2korr(end+3);
1582
if (pkt_length >= (uint) (end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1 -
1583
(char *) net->read_pos))
1584
strmake(drizzle->scramble+SCRAMBLE_LENGTH_323, end,
1585
SCRAMBLE_LENGTH-SCRAMBLE_LENGTH_323);
1587
drizzle->server_capabilities&= ~CLIENT_SECURE_CONNECTION;
1589
if (drizzle->options.secure_auth && passwd[0] &&
1590
!(drizzle->server_capabilities & CLIENT_SECURE_CONNECTION))
1592
set_drizzle_error(drizzle, CR_SECURE_AUTH, unknown_sqlstate);
1596
if (drizzle_init_character_set(drizzle))
1599
/* Save connection information */
1600
if (!my_multi_malloc(MYF(0),
1601
&drizzle->host_info, (uint) strlen(host_info)+1,
1602
&drizzle->host, (uint) strlen(host)+1,
1603
&drizzle->unix_socket,unix_socket ?
1604
(uint) strlen(unix_socket)+1 : (uint) 1,
1605
&drizzle->server_version,
1606
(uint) (end - (char*) net->read_pos),
1608
!(drizzle->user=my_strdup(user,MYF(0))) ||
1609
!(drizzle->passwd=my_strdup(passwd,MYF(0))))
1611
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
1614
strmov(drizzle->host_info,host_info);
1615
strmov(drizzle->host,host);
1617
strmov(drizzle->unix_socket,unix_socket);
1619
drizzle->unix_socket=0;
1620
strmov(drizzle->server_version,(char*) net->read_pos+1);
1624
Part 2: format and send client info to the server for access check
1627
client_flag|=drizzle->options.client_flag;
1628
client_flag|=CLIENT_CAPABILITIES;
1629
if (client_flag & CLIENT_MULTI_STATEMENTS)
1630
client_flag|= CLIENT_MULTI_RESULTS;
1633
client_flag|=CLIENT_CONNECT_WITH_DB;
1635
/* Remove options that server doesn't support */
1636
client_flag= ((client_flag &
1637
~(CLIENT_COMPRESS | CLIENT_SSL | CLIENT_PROTOCOL_41)) |
1638
(client_flag & drizzle->server_capabilities));
1639
client_flag&= ~CLIENT_COMPRESS;
1641
if (client_flag & CLIENT_PROTOCOL_41)
1643
/* 4.1 server and 4.1 client has a 32 byte option flag */
1644
int4store(buff,client_flag);
1645
int4store(buff+4, net->max_packet_size);
1646
buff[8]= (char) drizzle->charset->number;
1647
bzero(buff+9, 32-9);
1652
int2store(buff,client_flag);
1653
int3store(buff+2,net->max_packet_size);
1656
drizzle->client_flag=client_flag;
1658
/* This needs to be changed as it's not useful with big packets */
1659
if (user && user[0])
1660
strmake(end,user,USERNAME_LENGTH); /* Max user name */
1662
read_user_name((char*) end);
1664
/* We have to handle different version of handshake here */
1665
#ifdef _CUSTOMCONFIG_
1666
#include "_cust_libdrizzle.h"
1668
end= strend(end) + 1;
1672
*end++= SCRAMBLE_LENGTH;
1673
scramble(end, drizzle->scramble, passwd);
1674
end+= SCRAMBLE_LENGTH;
1678
*end++= '\0'; /* empty password */
1680
/* Add database if needed */
1681
if (db && (drizzle->server_capabilities & CLIENT_CONNECT_WITH_DB))
1683
end= strmake(end, db, NAME_LEN) + 1;
1684
drizzle->db= my_strdup(db,MYF(MY_WME));
1687
/* Write authentication package */
1688
if (my_net_write(net, (uchar*) buff, (size_t) (end-buff)) || net_flush(net))
1690
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1691
ER(CR_SERVER_LOST_EXTENDED),
1692
"sending authentication information",
1698
Part 3: Authorization data's been sent. Now server can reply with
1699
OK-packet, or re-request scrambled password.
1702
if ((pkt_length=cli_safe_read(drizzle)) == packet_error)
1704
if (drizzle->net.last_errno == CR_SERVER_LOST)
1705
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1706
ER(CR_SERVER_LOST_EXTENDED),
1707
"reading authorization packet",
1712
if (client_flag & CLIENT_COMPRESS) /* We will use compression */
1716
if (db && drizzle_select_db(drizzle, db))
1718
if (drizzle->net.last_errno == CR_SERVER_LOST)
1719
set_drizzle_extended_error(drizzle, CR_SERVER_LOST, unknown_sqlstate,
1720
ER(CR_SERVER_LOST_EXTENDED),
1721
"Setting intital database",
1726
if (drizzle->options.init_commands)
1728
DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
1729
char **ptr= (char**)init_commands->buffer;
1730
char **end_command= ptr + init_commands->elements;
1732
my_bool reconnect=drizzle->reconnect;
1733
drizzle->reconnect=0;
1735
for (; ptr < end_command; ptr++)
1738
if (drizzle_real_query(drizzle,*ptr, (ulong) strlen(*ptr)))
1740
if (drizzle->fields)
1742
if (!(res= cli_use_result(drizzle)))
1744
drizzle_free_result(res);
1747
drizzle->reconnect=reconnect;
1750
reset_sigpipe(drizzle);
1754
reset_sigpipe(drizzle);
1756
/* Free alloced memory */
1757
end_server(drizzle);
1758
drizzle_close_free(drizzle);
1759
if (!(((ulong) client_flag) & CLIENT_REMEMBER_OPTIONS))
1760
drizzle_close_free_options(drizzle);
1766
my_bool drizzle_reconnect(DRIZZLE *drizzle)
1768
DRIZZLE tmp_drizzle;
1771
if (!drizzle->reconnect ||
1772
(drizzle->server_status & SERVER_STATUS_IN_TRANS) || !drizzle->host_info)
1774
/* Allow reconnect next time */
1775
drizzle->server_status&= ~SERVER_STATUS_IN_TRANS;
1776
set_drizzle_error(drizzle, CR_SERVER_GONE_ERROR, unknown_sqlstate);
1779
drizzle_create(&tmp_drizzle);
1780
tmp_drizzle.options= drizzle->options;
1781
tmp_drizzle.options.my_cnf_file= tmp_drizzle.options.my_cnf_group= 0;
1783
if (!drizzle_connect(&tmp_drizzle,drizzle->host,drizzle->user,drizzle->passwd,
1784
drizzle->db, drizzle->port, drizzle->unix_socket,
1785
drizzle->client_flag | CLIENT_REMEMBER_OPTIONS))
1787
drizzle->net.last_errno= tmp_drizzle.net.last_errno;
1788
strmov(drizzle->net.last_error, tmp_drizzle.net.last_error);
1789
strmov(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
1792
if (drizzle_set_character_set(&tmp_drizzle, drizzle->charset->csname))
1794
bzero((char*) &tmp_drizzle.options,sizeof(tmp_drizzle.options));
1795
drizzle_close(&tmp_drizzle);
1796
drizzle->net.last_errno= tmp_drizzle.net.last_errno;
1797
strmov(drizzle->net.last_error, tmp_drizzle.net.last_error);
1798
strmov(drizzle->net.sqlstate, tmp_drizzle.net.sqlstate);
1802
tmp_drizzle.reconnect= 1;
1803
tmp_drizzle.free_me= drizzle->free_me;
1805
/* Don't free options as these are now used in tmp_drizzle */
1806
bzero((char*) &drizzle->options,sizeof(drizzle->options));
1808
drizzle_close(drizzle);
1809
*drizzle=tmp_drizzle;
1810
net_clear(&drizzle->net, 1);
1811
drizzle->affected_rows= ~(uint64_t) 0;
1816
/**************************************************************************
1817
Set current database
1818
**************************************************************************/
1821
drizzle_select_db(DRIZZLE *drizzle, const char *db)
1825
if ((error=simple_command(drizzle,COM_INIT_DB, (const uchar*) db,
1826
(ulong) strlen(db),0)))
1828
my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
1829
drizzle->db=my_strdup(db,MYF(MY_WME));
1834
/*************************************************************************
1835
Send a QUIT to the server and close the connection
1836
If handle is alloced by DRIZZLE connect free it.
1837
*************************************************************************/
1839
static void drizzle_close_free_options(DRIZZLE *drizzle)
1841
my_free(drizzle->options.user,MYF(MY_ALLOW_ZERO_PTR));
1842
my_free(drizzle->options.host,MYF(MY_ALLOW_ZERO_PTR));
1843
my_free(drizzle->options.password,MYF(MY_ALLOW_ZERO_PTR));
1844
my_free(drizzle->options.unix_socket,MYF(MY_ALLOW_ZERO_PTR));
1845
my_free(drizzle->options.db,MYF(MY_ALLOW_ZERO_PTR));
1846
my_free(drizzle->options.my_cnf_file,MYF(MY_ALLOW_ZERO_PTR));
1847
my_free(drizzle->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
1848
my_free(drizzle->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
1849
my_free(drizzle->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
1850
my_free(drizzle->options.client_ip,MYF(MY_ALLOW_ZERO_PTR));
1851
if (drizzle->options.init_commands)
1853
DYNAMIC_ARRAY *init_commands= drizzle->options.init_commands;
1854
char **ptr= (char**)init_commands->buffer;
1855
char **end= ptr + init_commands->elements;
1856
for (; ptr<end; ptr++)
1857
my_free(*ptr,MYF(MY_WME));
1858
delete_dynamic(init_commands);
1859
my_free((char*)init_commands,MYF(MY_WME));
1862
if (drizzle->options.shared_memory_base_name != def_shared_memory_base_name)
1863
my_free(drizzle->options.shared_memory_base_name,MYF(MY_ALLOW_ZERO_PTR));
1864
#endif /* HAVE_SMEM */
1865
bzero((char*) &drizzle->options,sizeof(drizzle->options));
1870
static void drizzle_close_free(DRIZZLE *drizzle)
1872
my_free((uchar*) drizzle->host_info,MYF(MY_ALLOW_ZERO_PTR));
1873
my_free(drizzle->user,MYF(MY_ALLOW_ZERO_PTR));
1874
my_free(drizzle->passwd,MYF(MY_ALLOW_ZERO_PTR));
1875
my_free(drizzle->db,MYF(MY_ALLOW_ZERO_PTR));
1876
my_free(drizzle->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
1877
drizzle->info_buffer= 0;
1879
/* Clear pointers for better safety */
1880
drizzle->host_info= drizzle->user= drizzle->passwd= drizzle->db= 0;
1884
void STDCALL drizzle_close(DRIZZLE *drizzle)
1886
if (drizzle) /* Some simple safety */
1888
/* If connection is still up, send a QUIT message */
1889
if (drizzle->net.vio != 0)
1891
free_old_query(drizzle);
1892
drizzle->status=DRIZZLE_STATUS_READY; /* Force command */
1893
drizzle->reconnect=0;
1894
simple_command(drizzle,COM_QUIT,(uchar*) 0,0,1);
1895
end_server(drizzle); /* Sets drizzle->net.vio= 0 */
1897
drizzle_close_free_options(drizzle);
1898
drizzle_close_free(drizzle);
1899
if (drizzle->free_me)
1900
my_free((uchar*) drizzle,MYF(0));
1906
static bool cli_read_query_result(DRIZZLE *drizzle)
1910
DRIZZLE_DATA *fields;
1913
if ((length = cli_safe_read(drizzle)) == packet_error)
1915
free_old_query(drizzle); /* Free old result */
1916
#ifdef MYSQL_CLIENT /* Avoid warn of unused labels*/
1919
pos=(uchar*) drizzle->net.read_pos;
1920
if ((field_count= net_field_length(&pos)) == 0)
1922
drizzle->affected_rows= net_field_length_ll(&pos);
1923
drizzle->insert_id= net_field_length_ll(&pos);
1924
if (protocol_41(drizzle))
1926
drizzle->server_status=uint2korr(pos); pos+=2;
1927
drizzle->warning_count=uint2korr(pos); pos+=2;
1929
else if (drizzle->server_capabilities & CLIENT_TRANSACTIONS)
1931
/* DRIZZLE 4.0 protocol */
1932
drizzle->server_status=uint2korr(pos); pos+=2;
1933
drizzle->warning_count= 0;
1935
if (pos < drizzle->net.read_pos+length && net_field_length(&pos))
1936
drizzle->info=(char*) pos;
1940
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
1944
if (!(drizzle->options.client_flag & CLIENT_LOCAL_FILES))
1946
set_drizzle_error(drizzle, CR_MALFORMED_PACKET, unknown_sqlstate);
1950
error= handle_local_infile(drizzle,(char*) pos);
1951
if ((length= cli_safe_read(drizzle)) == packet_error || error)
1953
goto get_info; /* Get info packet */
1956
if (!(drizzle->server_status & SERVER_STATUS_AUTOCOMMIT))
1957
drizzle->server_status|= SERVER_STATUS_IN_TRANS;
1959
if (!(fields=cli_read_rows(drizzle,(DRIZZLE_FIELD*)0, protocol_41(drizzle) ? 7:5)))
1961
if (!(drizzle->fields=unpack_fields(fields,&drizzle->field_alloc,
1962
(uint) field_count,0,
1963
drizzle->server_capabilities)))
1965
drizzle->status= DRIZZLE_STATUS_GET_RESULT;
1966
drizzle->field_count= (uint) field_count;
1972
Send the query and return so we can do something else.
1973
Needs to be followed by drizzle_read_query_result() when we want to
1974
finish processing it.
1978
drizzle_send_query(DRIZZLE *drizzle, const char* query, uint32_t length)
1980
return(simple_command(drizzle, COM_QUERY, (uchar*) query, length, 1));
1985
drizzle_real_query(DRIZZLE *drizzle, const char *query, uint32_t length)
1987
if (drizzle_send_query(drizzle,query,length))
1989
return((int) (*drizzle->methods->read_query_result)(drizzle));
1993
/**************************************************************************
1994
Alloc result struct for buffered results. All rows are read to buffer.
1995
drizzle_data_seek may be used.
1996
**************************************************************************/
1998
DRIZZLE_RES * STDCALL drizzle_store_result(DRIZZLE *drizzle)
2000
DRIZZLE_RES *result;
2002
if (!drizzle->fields)
2004
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
2006
set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2009
drizzle->status=DRIZZLE_STATUS_READY; /* server is ready */
2010
if (!(result=(DRIZZLE_RES*) my_malloc((uint) (sizeof(DRIZZLE_RES)+
2012
drizzle->field_count),
2013
MYF(MY_WME | MY_ZEROFILL))))
2015
set_drizzle_error(drizzle, CR_OUT_OF_MEMORY, unknown_sqlstate);
2018
result->methods= drizzle->methods;
2019
result->eof= 1; /* Marker for buffered */
2020
result->lengths= (uint32_t*) (result+1);
2022
(*drizzle->methods->read_rows)(drizzle,drizzle->fields,drizzle->field_count)))
2024
my_free((uchar*) result,MYF(0));
2027
drizzle->affected_rows= result->row_count= result->data->rows;
2028
result->data_cursor= result->data->data;
2029
result->fields= drizzle->fields;
2030
result->field_alloc= drizzle->field_alloc;
2031
result->field_count= drizzle->field_count;
2032
/* The rest of result members is bzeroed in malloc */
2033
drizzle->fields=0; /* fields is now in result */
2034
clear_alloc_root(&drizzle->field_alloc);
2035
/* just in case this was mistakenly called after drizzle_stmt_execute() */
2036
drizzle->unbuffered_fetch_owner= 0;
2037
return(result); /* Data fetched */
2041
/**************************************************************************
2042
Alloc struct for use with unbuffered reads. Data is fetched by domand
2043
when calling to drizzle_fetch_row.
2044
DRIZZLE_DATA_seek is a noop.
2046
No other queries may be specified with the same DRIZZLE handle.
2047
There shouldn't be much processing per row because DRIZZLE server shouldn't
2048
have to wait for the client (and will not wait more than 30 sec/packet).
2049
**************************************************************************/
2051
static DRIZZLE_RES * cli_use_result(DRIZZLE *drizzle)
2053
DRIZZLE_RES *result;
2055
if (!drizzle->fields)
2057
if (drizzle->status != DRIZZLE_STATUS_GET_RESULT)
2059
set_drizzle_error(drizzle, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
2062
if (!(result=(DRIZZLE_RES*) my_malloc(sizeof(*result)+
2063
sizeof(ulong)*drizzle->field_count,
2064
MYF(MY_WME | MY_ZEROFILL))))
2066
result->lengths=(uint32_t*) (result+1);
2067
result->methods= drizzle->methods;
2068
if (!(result->row=(DRIZZLE_ROW)
2069
my_malloc(sizeof(result->row[0])*(drizzle->field_count+1), MYF(MY_WME))))
2070
{ /* Ptrs: to one row */
2071
my_free((uchar*) result,MYF(0));
2074
result->fields= drizzle->fields;
2075
result->field_alloc= drizzle->field_alloc;
2076
result->field_count= drizzle->field_count;
2077
result->current_field=0;
2078
result->handle= drizzle;
2079
result->current_row= 0;
2080
drizzle->fields=0; /* fields is now in result */
2081
clear_alloc_root(&drizzle->field_alloc);
2082
drizzle->status=DRIZZLE_STATUS_USE_RESULT;
2083
drizzle->unbuffered_fetch_owner= &result->unbuffered_fetch_cancelled;
2084
return(result); /* Data is read to be fetched */
428
2088
/**************************************************************************
429
2089
Return next row of the query results
430
2090
**************************************************************************/
433
2093
drizzle_fetch_row(DRIZZLE_RES *res)