1
/* Copyright (C) 2000-2004 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation.
7
There are special exceptions to the terms and conditions of the GPL as it
8
is applied to this software. View the full text of the exception in file
9
EXCEPTIONS-CLIENT in the directory of this software distribution.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20
#include <my_global.h>
23
#include <mysys_err.h>
27
#include "mysql_version.h"
28
#include "mysqld_error.h"
37
#if !defined(MSDOS) && !defined(__WIN__)
38
#include <sys/socket.h>
39
#include <netinet/in.h>
40
#include <arpa/inet.h>
45
#ifdef HAVE_SYS_SELECT_H
46
#include <sys/select.h>
48
#endif /* !defined(MSDOS) && !defined(__WIN__) */
55
#if defined(THREAD) && !defined(__WIN__)
56
#include <my_pthread.h> /* because of signal() */
59
#define INADDR_NONE -1
62
#include <sql_common.h>
63
#include "client_settings.h"
65
#undef net_buffer_length
66
#undef max_allowed_packet
68
ulong net_buffer_length=8192;
69
ulong max_allowed_packet= 1024L*1024L*1024L;
72
#ifdef EMBEDDED_LIBRARY
74
my_bool net_flush(NET *net);
77
#if defined(MSDOS) || defined(__WIN__)
78
/* socket_errno is defined in my_global.h for all platforms */
82
#define SOCKET_ERROR -1
86
If allowed through some configuration, then this needs to
89
#define MAX_LONG_DATA_LENGTH 8192
90
#define unsigned_field(A) ((A)->flags & UNSIGNED_FLAG)
92
static void append_wild(char *to,char *end,const char *wild);
93
sig_handler my_pipe_sig_handler(int sig);
95
static my_bool mysql_client_init= 0;
96
static my_bool org_my_init_done= 0;
100
Initialize the MySQL client library
106
Should be called before doing any other calls to the MySQL
107
client library to initialize thread specific variables etc.
108
It's called by mysql_init() to ensure that things will work for
109
old not threaded applications that doesn't call mysql_server_init()
114
1 could not initialize environment (out of memory or thread keys)
117
int STDCALL mysql_server_init(int argc __attribute__((unused)),
118
char **argv __attribute__((unused)),
119
char **groups __attribute__((unused)))
122
if (!mysql_client_init)
125
org_my_init_done=my_init_done;
126
if (my_init()) /* Will init threads */
131
mysql_port = MYSQL_PORT;
134
struct servent *serv_ptr;
138
if builder specifically requested a default port, use that
139
(even if it coincides with our factory default).
140
only if they didn't do we check /etc/services (and, failing
141
on that, fall back to the factory default of 3306).
142
either default can be overridden by the environment variable
143
MYSQL_TCP_PORT, which in turn can be overridden with command
147
#if MYSQL_PORT_DEFAULT == 0
148
if ((serv_ptr = getservbyname("mysql", "tcp")))
149
mysql_port = (uint) ntohs((ushort) serv_ptr->s_port);
151
if ((env = getenv("MYSQL_TCP_PORT")))
152
mysql_port =(uint) atoi(env);
156
if (!mysql_unix_port)
160
mysql_unix_port = (char*) MYSQL_NAMEDPIPE;
162
mysql_unix_port = (char*) MYSQL_UNIX_ADDR;
164
if ((env = getenv("MYSQL_UNIX_PORT")))
165
mysql_unix_port = env;
168
#if defined(SIGPIPE) && !defined(__WIN__) && !defined(__NETWARE__)
169
(void) signal(SIGPIPE, SIG_IGN);
171
#ifdef EMBEDDED_LIBRARY
173
result= init_embedded_server(argc, argv, groups);
178
result= (int)my_thread_init(); /* Init if new thread */
185
Free all memory and resources used by the client library
188
When calling this there should not be any other threads using
191
To make things simpler when used with windows dll's (which calls this
192
function automaticly), it's safe to call this function multiple times.
196
void STDCALL mysql_server_end()
198
if (!mysql_client_init)
201
#ifdef EMBEDDED_LIBRARY
202
end_embedded_server();
204
finish_client_errs();
207
/* If library called my_init(), free memory allocated by it */
208
if (!org_my_init_done)
210
my_end(MY_DONT_FREE_DBUG);
211
/* Remove TRACING, if enabled by mysql_debug() */
220
mysql_client_init= org_my_init_done= 0;
221
#ifdef EMBEDDED_SERVER
224
fclose(stderror_file);
230
static MYSQL_PARAMETERS mysql_internal_parameters=
231
{&max_allowed_packet, &net_buffer_length, 0};
233
MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void)
235
return &mysql_internal_parameters;
238
my_bool STDCALL mysql_thread_init()
241
return my_thread_init();
247
void STDCALL mysql_thread_end()
256
Expand wildcard to a sql string
260
append_wild(char *to, char *end, const char *wild)
262
end-=5; /* Some extra */
265
to=strmov(to," like '");
266
while (*wild && to < end)
268
if (*wild == '\\' || *wild == '\'')
272
if (*wild) /* Too small buffer */
273
*to++='%'; /* Nicer this way */
280
/**************************************************************************
281
Init debugging if MYSQL_DEBUG environment variable is found
282
**************************************************************************/
285
mysql_debug(const char *debug __attribute__((unused)))
293
else if ((env = getenv("MYSQL_DEBUG")))
296
#if !defined(_WINVER) && !defined(WINVER)
297
puts("\n-------------------------------------------------------");
298
puts("MYSQL_DEBUG found. libmysql started with the following:");
300
puts("-------------------------------------------------------\n");
304
buff[sizeof(buff)-1]= 0;
305
strxnmov(buff,sizeof(buff)-1,"libmysql: ", env, NullS);
306
MessageBox((HWND) 0,"Debugging variable MYSQL_DEBUG used",buff,MB_OK);
314
/**************************************************************************
315
Ignore SIGPIPE handler
317
**************************************************************************/
320
my_pipe_sig_handler(int sig __attribute__((unused)))
322
DBUG_PRINT("info",("Hit by signal %d",sig));
323
#ifdef DONT_REMEMBER_SIGNAL
324
(void) signal(SIGPIPE, my_pipe_sig_handler);
329
/**************************************************************************
330
Connect to sql server
331
If host == 0 then use localhost
332
**************************************************************************/
334
#ifdef USE_OLD_FUNCTIONS
336
mysql_connect(MYSQL *mysql,const char *host,
337
const char *user, const char *passwd)
340
mysql=mysql_init(mysql); /* Make it thread safe */
342
DBUG_ENTER("mysql_connect");
343
if (!(res=mysql_real_connect(mysql,host,user,passwd,NullS,0,NullS,0)))
346
my_free((uchar*) mysql,MYF(0));
355
/**************************************************************************
356
Change user and database
357
**************************************************************************/
359
int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd)
361
NET *net= &mysql->net;
364
pkt_length= cli_safe_read(mysql);
366
if (pkt_length == packet_error)
369
if (pkt_length == 1 && net->read_pos[0] == 254 &&
370
mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
373
By sending this very specific reply server asks us to send scrambled
374
password in old format. The reply contains scramble_323.
376
scramble_323(buff, mysql->scramble, passwd);
377
if (my_net_write(net, (uchar*) buff, SCRAMBLE_LENGTH_323 + 1) ||
380
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
383
/* Read what server thinks about out new auth message report */
384
if (cli_safe_read(mysql) == packet_error)
390
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
391
const char *passwd, const char *db)
393
char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2];
396
CHARSET_INFO *saved_cs= mysql->charset;
398
DBUG_ENTER("mysql_change_user");
400
/* Get the connection-default character set. */
402
if (mysql_init_character_set(mysql))
404
mysql->charset= saved_cs;
408
/* Use an empty string instead of NULL. */
415
/* Store user into the buffer */
416
end= strmake(end, user, USERNAME_LENGTH) + 1;
418
/* write scrambled password according to server capabilities */
421
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
423
*end++= SCRAMBLE_LENGTH;
424
scramble(end, mysql->scramble, passwd);
425
end+= SCRAMBLE_LENGTH;
429
scramble_323(end, mysql->scramble, passwd);
430
end+= SCRAMBLE_LENGTH_323 + 1;
434
*end++= '\0'; /* empty password */
435
/* Add database if needed */
436
end= strmake(end, db ? db : "", NAME_LEN) + 1;
438
/* Add character set number. */
440
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
442
int2store(end, (ushort) mysql->charset->number);
446
/* Write authentication package */
447
simple_command(mysql,COM_CHANGE_USER, (uchar*) buff, (ulong) (end-buff), 1);
449
rc= (*mysql->methods->read_change_user_result)(mysql, buff, passwd);
452
The server will close all statements no matter was the attempt
453
to change user successful or not.
455
mysql_detach_stmt_list(&mysql->stmts, "mysql_change_user");
458
/* Free old connect information */
459
my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
460
my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
461
my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
463
/* alloc new connect information */
464
mysql->user= my_strdup(user,MYF(MY_WME));
465
mysql->passwd=my_strdup(passwd,MYF(MY_WME));
466
mysql->db= db ? my_strdup(db,MYF(MY_WME)) : 0;
470
mysql->charset= saved_cs;
476
#if defined(HAVE_GETPWUID) && defined(NO_GETPWUID_DECL)
477
struct passwd *getpwuid(uid_t);
478
char* getlogin(void);
481
#if defined(__NETWARE__)
482
/* Default to value of USER on NetWare, if unset use "UNKNOWN_USER" */
483
void read_user_name(char *name)
485
char *str=getenv("USER");
486
strmake(name, str ? str : "UNKNOWN_USER", USERNAME_LENGTH);
489
#elif !defined(MSDOS) && ! defined(VMS) && !defined(__WIN__)
491
void read_user_name(char *name)
493
DBUG_ENTER("read_user_name");
495
(void) strmov(name,"root"); /* allow use of surun */
501
if ((str=getlogin()) == NULL)
503
if ((skr=getpwuid(geteuid())) != NULL)
505
else if (!(str=getenv("USER")) && !(str=getenv("LOGNAME")) &&
506
!(str=getenv("LOGIN")))
509
(void) strmake(name,str,USERNAME_LENGTH);
511
(void) cuserid(name);
513
strmov(name,"UNKNOWN_USER");
519
#else /* If MSDOS || VMS */
521
void read_user_name(char *name)
523
char *str=getenv("USER"); /* ODBC will send user variable */
524
strmake(name,str ? str : "ODBC", USERNAME_LENGTH);
529
my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
532
uint packet_length=MY_ALIGN(mysql->net.max_packet-16,IO_SIZE);
533
NET *net= &mysql->net;
535
void *li_ptr; /* pass state to local_infile functions */
536
char *buf; /* buffer to be filled by local_infile_read */
537
struct st_mysql_options *options= &mysql->options;
538
DBUG_ENTER("handle_local_infile");
540
/* check that we've got valid callback functions */
541
if (!(options->local_infile_init &&
542
options->local_infile_read &&
543
options->local_infile_end &&
544
options->local_infile_error))
546
/* if any of the functions is invalid, set the default */
547
mysql_set_local_infile_default(mysql);
550
/* copy filename into local memory and allocate read buffer */
551
if (!(buf=my_malloc(packet_length, MYF(0))))
553
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
557
/* initialize local infile (open file, usually) */
558
if ((*options->local_infile_init)(&li_ptr, net_filename,
559
options->local_infile_userdata))
561
VOID(my_net_write(net,(const uchar*) "",0)); /* Server needs one packet */
563
strmov(net->sqlstate, unknown_sqlstate);
565
(*options->local_infile_error)(li_ptr,
567
sizeof(net->last_error)-1);
571
/* read blocks of data from local infile callback */
573
(*options->local_infile_read)(li_ptr, buf,
576
if (my_net_write(net, (uchar*) buf, readcount))
579
("Lost connection to MySQL server during LOAD DATA of local file"));
580
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
585
/* Send empty packet to mark end of file */
586
if (my_net_write(net, (const uchar*) "", 0) || net_flush(net))
588
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
595
(*options->local_infile_error)(li_ptr,
597
sizeof(net->last_error)-1);
604
/* free up memory allocated with _init, usually */
605
(*options->local_infile_end)(li_ptr);
606
my_free(buf, MYF(0));
611
/****************************************************************************
612
Default handlers for LOAD LOCAL INFILE
613
****************************************************************************/
615
typedef struct st_default_local_infile
619
const char *filename;
620
char error_msg[LOCAL_INFILE_ERROR_LEN];
621
} default_local_infile_data;
625
Open file for LOAD LOCAL INFILE
628
default_local_infile_init()
629
ptr Store pointer to internal data here
630
filename File name to open. This may be in unix format !
634
Even if this function returns an error, the load data interface
635
guarantees that default_local_infile_end() is called.
642
static int default_local_infile_init(void **ptr, const char *filename,
643
void *userdata __attribute__ ((unused)))
645
default_local_infile_data *data;
646
char tmp_name[FN_REFLEN];
648
if (!(*ptr= data= ((default_local_infile_data *)
649
my_malloc(sizeof(default_local_infile_data), MYF(0)))))
650
return 1; /* out of memory */
652
data->error_msg[0]= 0;
654
data->filename= filename;
656
fn_format(tmp_name, filename, "", "", MY_UNPACK_FILENAME);
657
if ((data->fd = my_open(tmp_name, O_RDONLY, MYF(0))) < 0)
659
data->error_num= my_errno;
660
my_snprintf(data->error_msg, sizeof(data->error_msg)-1,
661
EE(EE_FILENOTFOUND), tmp_name, data->error_num);
669
Read data for LOAD LOCAL INFILE
672
default_local_infile_read()
673
ptr Points to handle allocated by _init
675
buf_len Ammount of data to read
678
> 0 number of bytes read
683
static int default_local_infile_read(void *ptr, char *buf, uint buf_len)
686
default_local_infile_data*data = (default_local_infile_data *) ptr;
688
if ((count= (int) my_read(data->fd, (uchar *) buf, buf_len, MYF(0))) < 0)
690
data->error_num= EE_READ; /* the errmsg for not entire file read */
691
my_snprintf(data->error_msg, sizeof(data->error_msg)-1,
693
data->filename, my_errno);
700
Read data for LOAD LOCAL INFILE
703
default_local_infile_end()
704
ptr Points to handle allocated by _init
705
May be NULL if _init failed!
710
static void default_local_infile_end(void *ptr)
712
default_local_infile_data *data= (default_local_infile_data *) ptr;
713
if (data) /* If not error on open */
716
my_close(data->fd, MYF(MY_WME));
717
my_free(ptr, MYF(MY_WME));
723
Return error from LOAD LOCAL INFILE
726
default_local_infile_end()
727
ptr Points to handle allocated by _init
728
May be NULL if _init failed!
729
error_msg Store error text here
730
error_msg_len Max lenght of error_msg
737
default_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
739
default_local_infile_data *data = (default_local_infile_data *) ptr;
740
if (data) /* If not error on open */
742
strmake(error_msg, data->error_msg, error_msg_len);
743
return data->error_num;
745
/* This can only happen if we got error on malloc of handle */
746
strmov(error_msg, ER(CR_OUT_OF_MEMORY));
747
return CR_OUT_OF_MEMORY;
752
mysql_set_local_infile_handler(MYSQL *mysql,
753
int (*local_infile_init)(void **, const char *,
755
int (*local_infile_read)(void *, char *, uint),
756
void (*local_infile_end)(void *),
757
int (*local_infile_error)(void *, char *, uint),
760
mysql->options.local_infile_init= local_infile_init;
761
mysql->options.local_infile_read= local_infile_read;
762
mysql->options.local_infile_end= local_infile_end;
763
mysql->options.local_infile_error= local_infile_error;
764
mysql->options.local_infile_userdata = userdata;
768
void mysql_set_local_infile_default(MYSQL *mysql)
770
mysql->options.local_infile_init= default_local_infile_init;
771
mysql->options.local_infile_read= default_local_infile_read;
772
mysql->options.local_infile_end= default_local_infile_end;
773
mysql->options.local_infile_error= default_local_infile_error;
777
/**************************************************************************
778
Do a query. If query returned rows, free old rows.
779
Read data by mysql_store_result or by repeat call of mysql_fetch_row
780
**************************************************************************/
783
mysql_query(MYSQL *mysql, const char *query)
785
return mysql_real_query(mysql,query, (uint) strlen(query));
789
/**************************************************************************
790
Return next field of the query results
791
**************************************************************************/
793
MYSQL_FIELD * STDCALL
794
mysql_fetch_field(MYSQL_RES *result)
796
if (result->current_field >= result->field_count)
798
return &result->fields[result->current_field++];
802
/**************************************************************************
803
Move to a specific row and column
804
**************************************************************************/
807
mysql_data_seek(MYSQL_RES *result, my_ulonglong row)
810
DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row));
812
for (tmp=result->data->data; row-- && tmp ; tmp = tmp->next) ;
813
result->current_row=0;
814
result->data_cursor = tmp;
818
/*************************************************************************
819
put the row or field cursor one a position one got from mysql_row_tell()
820
This doesn't restore any data. The next mysql_fetch_row or
821
mysql_fetch_field will return the next row or field after the last used
822
*************************************************************************/
824
MYSQL_ROW_OFFSET STDCALL
825
mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET row)
827
MYSQL_ROW_OFFSET return_value=result->data_cursor;
828
result->current_row= 0;
829
result->data_cursor= row;
834
MYSQL_FIELD_OFFSET STDCALL
835
mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET field_offset)
837
MYSQL_FIELD_OFFSET return_value=result->current_field;
838
result->current_field=field_offset;
843
/*****************************************************************************
845
*****************************************************************************/
848
mysql_list_dbs(MYSQL *mysql, const char *wild)
851
DBUG_ENTER("mysql_list_dbs");
853
append_wild(strmov(buff,"show databases"),buff+sizeof(buff),wild);
854
if (mysql_query(mysql,buff))
856
DBUG_RETURN (mysql_store_result(mysql));
860
/*****************************************************************************
861
List all tables in a database
862
If wild is given then only the tables matching wild is returned
863
*****************************************************************************/
866
mysql_list_tables(MYSQL *mysql, const char *wild)
869
DBUG_ENTER("mysql_list_tables");
871
append_wild(strmov(buff,"show tables"),buff+sizeof(buff),wild);
872
if (mysql_query(mysql,buff))
874
DBUG_RETURN (mysql_store_result(mysql));
878
MYSQL_FIELD *cli_list_fields(MYSQL *mysql)
881
if (!(query= cli_read_rows(mysql,(MYSQL_FIELD*) 0,
882
protocol_41(mysql) ? 8 : 6)))
885
mysql->field_count= (uint) query->rows;
886
return unpack_fields(query,&mysql->field_alloc,
887
mysql->field_count, 1, mysql->server_capabilities);
891
/**************************************************************************
892
List all fields in a table
893
If wild is given then only the fields matching wild is returned
894
Instead of this use query:
895
show fields in 'table' like "wild"
896
**************************************************************************/
899
mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)
904
DBUG_ENTER("mysql_list_fields");
905
DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : ""));
907
end=strmake(strmake(buff, table,128)+1,wild ? wild : "",128);
908
free_old_query(mysql);
909
if (simple_command(mysql, COM_FIELD_LIST, (uchar*) buff,
910
(ulong) (end-buff), 1) ||
911
!(fields= (*mysql->methods->list_fields)(mysql)))
914
if (!(result = (MYSQL_RES *) my_malloc(sizeof(MYSQL_RES),
915
MYF(MY_WME | MY_ZEROFILL))))
918
result->methods= mysql->methods;
919
result->field_alloc=mysql->field_alloc;
921
result->field_count = mysql->field_count;
922
result->fields= fields;
927
/* List all running processes (threads) in server */
930
mysql_list_processes(MYSQL *mysql)
935
DBUG_ENTER("mysql_list_processes");
937
if (simple_command(mysql,COM_PROCESS_INFO,0,0,0))
939
free_old_query(mysql);
940
pos=(uchar*) mysql->net.read_pos;
941
field_count=(uint) net_field_length(&pos);
942
if (!(fields = (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*) 0,
943
protocol_41(mysql) ? 7 : 5)))
945
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0,
946
mysql->server_capabilities)))
948
mysql->status=MYSQL_STATUS_GET_RESULT;
949
mysql->field_count=field_count;
950
DBUG_RETURN(mysql_store_result(mysql));
954
#ifdef USE_OLD_FUNCTIONS
956
mysql_create_db(MYSQL *mysql, const char *db)
958
DBUG_ENTER("mysql_createdb");
959
DBUG_PRINT("enter",("db: %s",db));
960
DBUG_RETURN(simple_command(mysql,COM_CREATE_DB,db, (ulong) strlen(db),0));
965
mysql_drop_db(MYSQL *mysql, const char *db)
967
DBUG_ENTER("mysql_drop_db");
968
DBUG_PRINT("enter",("db: %s",db));
969
DBUG_RETURN(simple_command(mysql,COM_DROP_DB,db,(ulong) strlen(db),0));
975
mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level)
978
DBUG_ENTER("mysql_shutdown");
979
level[0]= (uchar) shutdown_level;
980
DBUG_RETURN(simple_command(mysql, COM_SHUTDOWN, level, 1, 0));
985
mysql_refresh(MYSQL *mysql,uint options)
988
DBUG_ENTER("mysql_refresh");
989
bits[0]= (uchar) options;
990
DBUG_RETURN(simple_command(mysql, COM_REFRESH, bits, 1, 0));
995
mysql_kill(MYSQL *mysql,ulong pid)
998
DBUG_ENTER("mysql_kill");
1000
DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,sizeof(buff),0));
1005
mysql_set_server_option(MYSQL *mysql, enum enum_mysql_set_option option)
1008
DBUG_ENTER("mysql_set_server_option");
1009
int2store(buff, (uint) option);
1010
DBUG_RETURN(simple_command(mysql, COM_SET_OPTION, buff, sizeof(buff), 0));
1015
mysql_dump_debug_info(MYSQL *mysql)
1017
DBUG_ENTER("mysql_dump_debug_info");
1018
DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
1022
const char *cli_read_statistics(MYSQL *mysql)
1024
mysql->net.read_pos[mysql->packet_length]=0; /* End of stat string */
1025
if (!mysql->net.read_pos[0])
1027
set_mysql_error(mysql, CR_WRONG_HOST_INFO, unknown_sqlstate);
1028
return mysql->net.last_error;
1030
return (char*) mysql->net.read_pos;
1034
const char * STDCALL
1035
mysql_stat(MYSQL *mysql)
1037
DBUG_ENTER("mysql_stat");
1038
if (simple_command(mysql,COM_STATISTICS,0,0,0))
1039
DBUG_RETURN(mysql->net.last_error);
1040
DBUG_RETURN((*mysql->methods->read_statistics)(mysql));
1045
mysql_ping(MYSQL *mysql)
1048
DBUG_ENTER("mysql_ping");
1049
res= simple_command(mysql,COM_PING,0,0,0);
1050
if (res == CR_SERVER_LOST && mysql->reconnect)
1051
res= simple_command(mysql,COM_PING,0,0,0);
1056
const char * STDCALL
1057
mysql_get_server_info(MYSQL *mysql)
1059
return((char*) mysql->server_version);
1063
const char * STDCALL
1064
mysql_get_host_info(MYSQL *mysql)
1066
return(mysql->host_info);
1071
mysql_get_proto_info(MYSQL *mysql)
1073
return (mysql->protocol_version);
1076
const char * STDCALL
1077
mysql_get_client_info(void)
1079
return (char*) MYSQL_SERVER_VERSION;
1082
ulong STDCALL mysql_get_client_version(void)
1084
return MYSQL_VERSION_ID;
1087
my_bool STDCALL mysql_eof(MYSQL_RES *res)
1092
MYSQL_FIELD * STDCALL mysql_fetch_field_direct(MYSQL_RES *res,uint fieldnr)
1094
return &(res)->fields[fieldnr];
1097
MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res)
1099
return (res)->fields;
1102
MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res)
1104
return res->data_cursor;
1107
MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res)
1109
return (res)->current_field;
1114
unsigned int STDCALL mysql_field_count(MYSQL *mysql)
1116
return mysql->field_count;
1119
my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql)
1121
return mysql->affected_rows;
1124
my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql)
1126
return mysql->insert_id;
1129
const char *STDCALL mysql_sqlstate(MYSQL *mysql)
1131
return mysql ? mysql->net.sqlstate : cant_connect_sqlstate;
1134
uint STDCALL mysql_warning_count(MYSQL *mysql)
1136
return mysql->warning_count;
1139
const char *STDCALL mysql_info(MYSQL *mysql)
1144
ulong STDCALL mysql_thread_id(MYSQL *mysql)
1146
return (mysql)->thread_id;
1149
const char * STDCALL mysql_character_set_name(MYSQL *mysql)
1151
return mysql->charset->csname;
1154
void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *csinfo)
1156
csinfo->number = mysql->charset->number;
1157
csinfo->state = mysql->charset->state;
1158
csinfo->csname = mysql->charset->csname;
1159
csinfo->name = mysql->charset->name;
1160
csinfo->comment = mysql->charset->comment;
1161
csinfo->mbminlen = mysql->charset->mbminlen;
1162
csinfo->mbmaxlen = mysql->charset->mbmaxlen;
1164
if (mysql->options.charset_dir)
1165
csinfo->dir = mysql->options.charset_dir;
1167
csinfo->dir = charsets_dir;
1170
uint STDCALL mysql_thread_safe(void)
1180
my_bool STDCALL mysql_embedded(void)
1182
#ifdef EMBEDDED_LIBRARY
1189
/****************************************************************************
1190
Some support functions
1191
****************************************************************************/
1194
Functions called my my_net_init() to set some application specific variables
1197
void my_net_local_init(NET *net)
1199
net->max_packet= (uint) net_buffer_length;
1200
my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
1201
my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
1202
net->retry_count= 1;
1203
net->max_packet_size= max(net_buffer_length, max_allowed_packet);
1207
This function is used to create HEX string that you
1208
can use in a SQL statement in of the either ways:
1209
INSERT INTO blob_column VALUES (0xAABBCC); (any MySQL version)
1210
INSERT INTO blob_column VALUES (X'AABBCC'); (4.1 and higher)
1212
The string in "from" is encoded to a HEX string.
1213
The result is placed in "to" and a terminating null byte is appended.
1215
The string pointed to by "from" must be "length" bytes long.
1216
You must allocate the "to" buffer to be at least length*2+1 bytes long.
1217
Each character needs two bytes, and you need room for the terminating
1218
null byte. When mysql_hex_string() returns, the contents of "to" will
1219
be a null-terminated string. The return value is the length of the
1220
encoded string, not including the terminating null character.
1222
The return value does not contain any leading 0x or a leading X' and
1223
trailing '. The caller must supply whichever of those is desired.
1227
mysql_hex_string(char *to, const char *from, ulong length)
1232
for (end= from + length; from < end; from++)
1234
*to++= _dig_vec_upper[((unsigned char) *from) >> 4];
1235
*to++= _dig_vec_upper[((unsigned char) *from) & 0x0F];
1238
return (ulong) (to-to0);
1242
Add escape characters to a string (blob?) to make it suitable for a insert
1243
to should at least have place for length*2+1 chars
1244
Returns the length of the to string
1248
mysql_escape_string(char *to,const char *from,ulong length)
1250
return escape_string_for_mysql(default_charset_info, to, 0, from, length);
1254
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
1257
if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
1258
return escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
1259
return escape_string_for_mysql(mysql->charset, to, 0, from, length);
1263
myodbc_remove_escape(MYSQL *mysql,char *name)
1267
my_bool use_mb_flag=use_mb(mysql->charset);
1270
for (end=name; *end ; end++) ;
1273
for (to=name ; *name ; name++)
1277
if (use_mb_flag && (l = my_ismbchar( mysql->charset, name , end ) ) )
1285
if (*name == '\\' && name[1])
1292
/********************************************************************
1293
Implementation of new client API for 4.1 version.
1295
mysql_stmt_* are real prototypes used by applications.
1297
To make API work in embedded library all functions performing
1298
real I/O are prefixed with 'cli_' (abbreviated from 'Call Level
1299
Interface'). This functions are invoked via pointers set in
1300
MYSQL::methods structure. Embedded counterparts, prefixed with
1301
'emb_' reside in libmysqld/lib_sql.cc.
1302
*********************************************************************/
1304
/******************* Declarations ***********************************/
1306
/* Default number of rows fetched per one COM_STMT_FETCH command. */
1308
#define DEFAULT_PREFETCH_ROWS (ulong) 1
1311
These functions are called by function pointer MYSQL_STMT::read_row_func.
1312
Each function corresponds to one of the read methods:
1313
- mysql_stmt_fetch without prior mysql_stmt_store_result,
1314
- mysql_stmt_fetch when result is stored,
1315
- mysql_stmt_fetch when there are no rows (always returns MYSQL_NO_DATA)
1318
static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row);
1319
static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row);
1320
static int stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row);
1321
static int stmt_read_row_no_data(MYSQL_STMT *stmt, unsigned char **row);
1322
static int stmt_read_row_no_result_set(MYSQL_STMT *stmt, unsigned char **row);
1325
This function is used in mysql_stmt_store_result if
1326
STMT_ATTR_UPDATE_MAX_LENGTH attribute is set.
1328
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data);
1329
static my_bool setup_one_fetch_function(MYSQL_BIND *, MYSQL_FIELD *field);
1331
/* Auxilary function used to reset statement handle. */
1333
#define RESET_SERVER_SIDE 1
1334
#define RESET_LONG_DATA 2
1335
#define RESET_STORE_RESULT 4
1337
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags);
1340
Maximum sizes of MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME
1341
values stored in network buffer.
1344
/* 1 (length) + 2 (year) + 1 (month) + 1 (day) */
1345
#define MAX_DATE_REP_LENGTH 5
1348
1 (length) + 1 (is negative) + 4 (day count) + 1 (hour)
1349
+ 1 (minute) + 1 (seconds) + 4 (microseconds)
1351
#define MAX_TIME_REP_LENGTH 13
1354
1 (length) + 2 (year) + 1 (month) + 1 (day) +
1355
1 (hour) + 1 (minute) + 1 (second) + 4 (microseconds)
1357
#define MAX_DATETIME_REP_LENGTH 12
1359
#define MAX_DOUBLE_STRING_REP_LENGTH 331
1361
/* A macro to check truncation errors */
1363
#define IS_TRUNCATED(value, is_unsigned, min, max, umax) \
1364
((is_unsigned) ? (((value) > (umax) || (value) < 0) ? 1 : 0) : \
1365
(((value) > (max) || (value) < (min)) ? 1 : 0))
1367
#define BIND_RESULT_DONE 1
1369
We report truncations only if at least one of MYSQL_BIND::error
1370
pointers is set. In this case stmt->bind_result_done |-ed with
1373
#define REPORT_DATA_TRUNCATION 2
1375
/**************** Misc utility functions ****************************/
1378
Reallocate the NET package to have at least length bytes available.
1382
net The NET structure to modify.
1383
length Ensure that net->buff has space for at least
1384
this number of bytes.
1388
1 Error, i.e. out of memory or requested packet size is bigger
1389
than max_allowed_packet. The error code is stored in net->last_errno.
1392
static my_bool my_realloc_str(NET *net, ulong length)
1394
ulong buf_length= (ulong) (net->write_pos - net->buff);
1396
DBUG_ENTER("my_realloc_str");
1397
if (buf_length + length > net->max_packet)
1399
res= net_realloc(net, buf_length + length);
1402
strmov(net->sqlstate, unknown_sqlstate);
1403
strmov(net->last_error, ER(net->last_errno));
1405
net->write_pos= net->buff+ buf_length;
1411
static void stmt_clear_error(MYSQL_STMT *stmt)
1413
if (stmt->last_errno)
1415
stmt->last_errno= 0;
1416
stmt->last_error[0]= '\0';
1417
strmov(stmt->sqlstate, not_error_sqlstate);
1422
Set statement error code, sqlstate, and error message
1423
from given errcode and sqlstate.
1426
void set_stmt_error(MYSQL_STMT * stmt, int errcode,
1427
const char *sqlstate, const char *err)
1429
DBUG_ENTER("set_stmt_error");
1430
DBUG_PRINT("enter", ("error: %d '%s'", errcode, ER(errcode)));
1431
DBUG_ASSERT(stmt != 0);
1436
stmt->last_errno= errcode;
1437
strmov(stmt->last_error, ER(errcode));
1438
strmov(stmt->sqlstate, sqlstate);
1445
Set statement error code, sqlstate, and error message from NET.
1447
@param stmt a statement handle. Copy the error here.
1448
@param net mysql->net. Source of the error.
1451
void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net)
1453
DBUG_ENTER("set_stmt_errmsg");
1454
DBUG_PRINT("enter", ("error: %d/%s '%s'",
1458
DBUG_ASSERT(stmt != 0);
1460
stmt->last_errno= net->last_errno;
1461
if (net->last_error && net->last_error[0])
1462
strmov(stmt->last_error, net->last_error);
1463
strmov(stmt->sqlstate, net->sqlstate);
1469
Read and unpack server reply to COM_STMT_PREPARE command (sent from
1470
mysql_stmt_prepare).
1473
cli_read_prepare_result()
1474
mysql connection handle
1475
stmt statement handle
1482
my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
1485
uint field_count, param_count;
1486
ulong packet_length;
1487
MYSQL_DATA *fields_data;
1488
DBUG_ENTER("cli_read_prepare_result");
1490
if ((packet_length= cli_safe_read(mysql)) == packet_error)
1492
mysql->warning_count= 0;
1494
pos= (uchar*) mysql->net.read_pos;
1495
stmt->stmt_id= uint4korr(pos+1); pos+= 5;
1496
/* Number of columns in result set */
1497
field_count= uint2korr(pos); pos+= 2;
1498
/* Number of placeholders in the statement */
1499
param_count= uint2korr(pos); pos+= 2;
1500
if (packet_length >= 12)
1501
mysql->warning_count= uint2korr(pos+1);
1503
if (param_count != 0)
1505
MYSQL_DATA *param_data;
1507
/* skip parameters data: we don't support it yet */
1508
if (!(param_data= (*mysql->methods->read_rows)(mysql, (MYSQL_FIELD*)0, 7)))
1510
free_rows(param_data);
1513
if (field_count != 0)
1515
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
1516
mysql->server_status|= SERVER_STATUS_IN_TRANS;
1518
if (!(fields_data= (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,7)))
1520
if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root,
1522
mysql->server_capabilities)))
1525
stmt->field_count= field_count;
1526
stmt->param_count= (ulong) param_count;
1527
DBUG_PRINT("exit",("field_count: %u param_count: %u warning_count: %u",
1528
field_count, param_count, (uint) mysql->warning_count));
1535
Allocate memory and init prepared statement structure.
1539
mysql connection handle
1542
This is an entry point of the new API. Returned handle stands for
1543
a server-side prepared statement. Memory for this structure (~700
1544
bytes) is allocated using 'malloc'. Once created, the handle can be
1545
reused many times. Created statement handle is bound to connection
1546
handle provided to this call: its lifetime is limited by lifetime
1548
'mysql_stmt_init()' is a pure local call, server side structure is
1549
created only in mysql_stmt_prepare.
1550
Next steps you may want to make:
1551
- set a statement attribute (mysql_stmt_attr_set()),
1552
- prepare statement handle with a query (mysql_stmt_prepare()),
1553
- close statement handle and free its memory (mysql_stmt_close()),
1554
- reset statement with mysql_stmt_reset() (a no-op which will
1556
Behaviour of the rest of API calls on this statement is not defined yet
1557
(though we're working on making each wrong call sequence return
1561
statement structure upon success and NULL if out of
1565
MYSQL_STMT * STDCALL
1566
mysql_stmt_init(MYSQL *mysql)
1569
DBUG_ENTER("mysql_stmt_init");
1571
if (!(stmt= (MYSQL_STMT *) my_malloc(sizeof(MYSQL_STMT),
1572
MYF(MY_WME | MY_ZEROFILL))))
1574
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1578
init_alloc_root(&stmt->mem_root, 2048, 2048);
1579
init_alloc_root(&stmt->result.alloc, 4096, 4096);
1580
stmt->result.alloc.min_malloc= sizeof(MYSQL_ROWS);
1581
mysql->stmts= list_add(mysql->stmts, &stmt->list);
1582
stmt->list.data= stmt;
1583
stmt->state= MYSQL_STMT_INIT_DONE;
1585
stmt->read_row_func= stmt_read_row_no_result_set;
1586
stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS;
1587
strmov(stmt->sqlstate, not_error_sqlstate);
1588
/* The rest of statement members was bzeroed inside malloc */
1595
Prepare server side statement with query.
1598
mysql_stmt_prepare()
1599
stmt statement handle
1600
query statement to prepare
1601
length statement length
1604
Associate statement with statement handle. This is done both on
1605
client and server sides. At this point the server parses given query
1606
and creates an internal structure to represent it.
1607
Next steps you may want to make:
1608
- find out if this statement returns a result set by
1609
calling mysql_stmt_field_count(), and get result set metadata
1610
with mysql_stmt_result_metadata(),
1611
- if query contains placeholders, bind input parameters to placeholders
1612
using mysql_stmt_bind_param(),
1613
- otherwise proceed directly to mysql_stmt_execute().
1615
IMPLEMENTATION NOTES
1616
- if this is a re-prepare of the statement, first close previous data
1617
structure on the server and free old statement data
1618
- then send the query to server and get back number of placeholders,
1619
number of columns in result set (if any), and result set metadata.
1620
At the same time allocate memory for input and output parameters
1621
to have less checks in mysql_stmt_bind_{param, result}.
1629
mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
1631
MYSQL *mysql= stmt->mysql;
1632
DBUG_ENTER("mysql_stmt_prepare");
1636
/* mysql can be reset in mysql_close called from mysql_reconnect */
1637
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
1642
Reset the last error in any case: that would clear the statement
1643
if the previous prepare failed.
1645
stmt->last_errno= 0;
1646
stmt->last_error[0]= '\0';
1648
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
1650
/* This is second prepare with another statement */
1651
uchar buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
1653
if (reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT))
1656
These members must be reset for API to
1657
function in case of error or misuse.
1659
stmt->bind_param_done= stmt->bind_result_done= FALSE;
1660
stmt->param_count= stmt->field_count= 0;
1661
free_root(&stmt->mem_root, MYF(MY_KEEP_PREALLOC));
1663
int4store(buff, stmt->stmt_id);
1666
Close statement in server
1668
If there was a 'use' result from another statement, or from
1669
mysql_use_result it won't be freed in mysql_stmt_free_result and
1670
we should get 'Commands out of sync' here.
1672
stmt->state= MYSQL_STMT_INIT_DONE;
1673
if (stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt))
1675
set_stmt_errmsg(stmt, &mysql->net);
1680
if (stmt_command(mysql, COM_STMT_PREPARE, (const uchar*) query, length, stmt))
1682
set_stmt_errmsg(stmt, &mysql->net);
1686
if ((*mysql->methods->read_prepare_result)(mysql, stmt))
1688
set_stmt_errmsg(stmt, &mysql->net);
1693
alloc_root will return valid address even in case when param_count
1694
and field_count are zero. Thus we should never rely on stmt->bind
1695
or stmt->params when checking for existence of placeholders or
1698
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
1700
(stmt->param_count +
1701
stmt->field_count))))
1703
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
1706
stmt->bind= stmt->params + stmt->param_count;
1707
stmt->state= MYSQL_STMT_PREPARE_DONE;
1708
DBUG_PRINT("info", ("Parameter count: %u", stmt->param_count));
1713
Get result set metadata from reply to mysql_stmt_execute.
1714
This is used mainly for SHOW commands, as metadata for these
1715
commands is sent only with result set.
1716
To be removed when all commands will fully support prepared mode.
1719
static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
1721
MYSQL_FIELD *fields, *field, *end;
1722
MEM_ROOT *alloc= &stmt->mem_root;
1723
MYSQL *mysql= stmt->mysql;
1725
stmt->field_count= mysql->field_count;
1728
Get the field information for non-select statements
1729
like SHOW and DESCRIBE commands
1731
if (!(stmt->fields= (MYSQL_FIELD *) alloc_root(alloc,
1732
sizeof(MYSQL_FIELD) *
1733
stmt->field_count)) ||
1734
!(stmt->bind= (MYSQL_BIND *) alloc_root(alloc,
1735
sizeof(MYSQL_BIND) *
1736
stmt->field_count)))
1739
for (fields= mysql->fields, end= fields+stmt->field_count,
1740
field= stmt->fields;
1741
field && fields < end; fields++, field++)
1743
field->db = strdup_root(alloc,fields->db);
1744
field->table = strdup_root(alloc,fields->table);
1745
field->org_table= strdup_root(alloc,fields->org_table);
1746
field->name = strdup_root(alloc,fields->name);
1747
field->org_name = strdup_root(alloc,fields->org_name);
1748
field->charsetnr= fields->charsetnr;
1749
field->length = fields->length;
1750
field->type = fields->type;
1751
field->flags = fields->flags;
1752
field->decimals = fields->decimals;
1753
field->def = fields->def ? strdup_root(alloc,fields->def): 0;
1754
field->max_length= 0;
1756
return stmt->field_count;
1761
Update result set columns metadata if it was sent again in
1762
reply to COM_STMT_EXECUTE.
1765
static void update_stmt_fields(MYSQL_STMT *stmt)
1767
MYSQL_FIELD *field= stmt->mysql->fields;
1768
MYSQL_FIELD *field_end= field + stmt->field_count;
1769
MYSQL_FIELD *stmt_field= stmt->fields;
1770
MYSQL_BIND *my_bind= stmt->bind_result_done ? stmt->bind : 0;
1772
DBUG_ASSERT(stmt->field_count == stmt->mysql->field_count);
1774
for (; field < field_end; ++field, ++stmt_field)
1776
stmt_field->charsetnr= field->charsetnr;
1777
stmt_field->length = field->length;
1778
stmt_field->type = field->type;
1779
stmt_field->flags = field->flags;
1780
stmt_field->decimals = field->decimals;
1783
/* Ignore return value: it should be 0 if bind_result succeeded. */
1784
(void) setup_one_fetch_function(my_bind++, stmt_field);
1790
Returns prepared statement metadata in the form of a result set.
1793
mysql_stmt_result_metadata()
1794
stmt statement handle
1797
This function should be used after mysql_stmt_execute().
1798
You can safely check that prepared statement has a result set by calling
1799
mysql_stmt_field_count(): if number of fields is not zero, you can call
1800
this function to get fields metadata.
1801
Next steps you may want to make:
1802
- find out number of columns in result set by calling
1803
mysql_num_fields(res) (the same value is returned by
1804
mysql_stmt_field_count())
1805
- fetch metadata for any column with mysql_fetch_field,
1806
mysql_fetch_field_direct, mysql_fetch_fields, mysql_field_seek.
1807
- free returned MYSQL_RES structure with mysql_free_result.
1808
- proceed to binding of output parameters.
1811
NULL statement contains no result set or out of memory.
1812
In the latter case you can retreive error message
1813
with mysql_stmt_error.
1814
MYSQL_RES a result set with no rows
1818
mysql_stmt_result_metadata(MYSQL_STMT *stmt)
1821
DBUG_ENTER("mysql_stmt_result_metadata");
1824
stmt->fields is only defined if stmt->field_count is not null;
1825
stmt->field_count is initialized in prepare.
1827
if (!stmt->field_count)
1830
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result),
1831
MYF(MY_WME | MY_ZEROFILL))))
1833
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
1837
result->methods= stmt->mysql->methods;
1838
result->eof= 1; /* Marker for buffered */
1839
result->fields= stmt->fields;
1840
result->field_count= stmt->field_count;
1841
/* The rest of members of 'result' was bzeroed inside malloc */
1842
DBUG_RETURN(result);
1847
Returns parameter columns meta information in the form of
1851
mysql_stmt_param_metadata()
1852
stmt statement handle
1855
This function can be called after you prepared the statement handle
1856
with mysql_stmt_prepare().
1857
XXX: not implemented yet.
1860
MYSQL_RES on success, 0 if there is no metadata.
1861
Currently this function always returns 0.
1865
mysql_stmt_param_metadata(MYSQL_STMT *stmt)
1867
DBUG_ENTER("mysql_stmt_param_metadata");
1869
if (!stmt->param_count)
1873
TODO: Fix this when server sends the information.
1874
Till then keep a dummy prototype.
1880
/* Store type of parameter in network buffer. */
1882
static void store_param_type(char **pos, MYSQL_BIND *param)
1884
uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
1885
int2store(*pos, typecode);
1891
Functions to store parameter data in network packet.
1895
net MySQL NET connection
1896
param MySQL bind param
1899
These funtions are invoked from mysql_stmt_execute() by
1900
MYSQL_BIND::store_param_func pointer. This pointer is set once per
1901
many executions in mysql_stmt_bind_param(). The caller must ensure
1902
that network buffer have enough capacity to store parameter
1903
(MYSQL_BIND::buffer_length contains needed number of bytes).
1906
static void store_param_tinyint(NET *net, MYSQL_BIND *param)
1908
*(net->write_pos++)= *(uchar *) param->buffer;
1911
static void store_param_short(NET *net, MYSQL_BIND *param)
1913
short value= *(short*) param->buffer;
1914
int2store(net->write_pos,value);
1918
static void store_param_int32(NET *net, MYSQL_BIND *param)
1920
int32 value= *(int32*) param->buffer;
1921
int4store(net->write_pos,value);
1925
static void store_param_int64(NET *net, MYSQL_BIND *param)
1927
longlong value= *(longlong*) param->buffer;
1928
int8store(net->write_pos,value);
1932
static void store_param_float(NET *net, MYSQL_BIND *param)
1934
float value= *(float*) param->buffer;
1935
float4store(net->write_pos, value);
1939
static void store_param_double(NET *net, MYSQL_BIND *param)
1941
double value= *(double*) param->buffer;
1942
float8store(net->write_pos, value);
1946
static void store_param_time(NET *net, MYSQL_BIND *param)
1948
MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
1949
char buff[MAX_TIME_REP_LENGTH], *pos;
1953
pos[0]= tm->neg ? 1: 0;
1954
int4store(pos+1, tm->day);
1955
pos[5]= (uchar) tm->hour;
1956
pos[6]= (uchar) tm->minute;
1957
pos[7]= (uchar) tm->second;
1958
int4store(pos+8, tm->second_part);
1959
if (tm->second_part)
1961
else if (tm->hour || tm->minute || tm->second || tm->day)
1965
buff[0]= (char) length++;
1966
memcpy((char *)net->write_pos, buff, length);
1967
net->write_pos+= length;
1970
static void net_store_datetime(NET *net, MYSQL_TIME *tm)
1972
char buff[MAX_DATETIME_REP_LENGTH], *pos;
1977
int2store(pos, tm->year);
1978
pos[2]= (uchar) tm->month;
1979
pos[3]= (uchar) tm->day;
1980
pos[4]= (uchar) tm->hour;
1981
pos[5]= (uchar) tm->minute;
1982
pos[6]= (uchar) tm->second;
1983
int4store(pos+7, tm->second_part);
1984
if (tm->second_part)
1986
else if (tm->hour || tm->minute || tm->second)
1988
else if (tm->year || tm->month || tm->day)
1992
buff[0]= (char) length++;
1993
memcpy((char *)net->write_pos, buff, length);
1994
net->write_pos+= length;
1997
static void store_param_date(NET *net, MYSQL_BIND *param)
1999
MYSQL_TIME tm= *((MYSQL_TIME *) param->buffer);
2000
tm.hour= tm.minute= tm.second= tm.second_part= 0;
2001
net_store_datetime(net, &tm);
2004
static void store_param_datetime(NET *net, MYSQL_BIND *param)
2006
MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
2007
net_store_datetime(net, tm);
2010
static void store_param_str(NET *net, MYSQL_BIND *param)
2012
/* param->length is always set in mysql_stmt_bind_param */
2013
ulong length= *param->length;
2014
uchar *to= net_store_length(net->write_pos, length);
2015
memcpy(to, param->buffer, length);
2016
net->write_pos= to+length;
2021
Mark if the parameter is NULL.
2025
net MySQL NET connection
2026
param MySQL bind param
2029
A data package starts with a string of bits where we set a bit
2030
if a parameter is NULL. Unlike bit string in result set row, here
2031
we don't have reserved bits for OK/error packet.
2034
static void store_param_null(NET *net, MYSQL_BIND *param)
2036
uint pos= param->param_number;
2037
net->buff[pos/8]|= (uchar) (1 << (pos & 7));
2042
Store one parameter in network packet: data is read from
2043
client buffer and saved in network packet by means of one
2044
of store_param_xxxx functions.
2047
static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
2049
NET *net= &stmt->mysql->net;
2050
DBUG_ENTER("store_param");
2051
DBUG_PRINT("enter",("type: %d buffer: 0x%lx length: %lu is_null: %d",
2053
(long) (param->buffer ? param->buffer : NullS),
2054
*param->length, *param->is_null));
2056
if (*param->is_null)
2057
store_param_null(net, param);
2061
Param->length should ALWAYS point to the correct length for the type
2062
Either to the length pointer given by the user or param->buffer_length
2064
if ((my_realloc_str(net, *param->length)))
2066
set_stmt_errmsg(stmt, net);
2069
(*param->store_param_func)(net, param);
2076
Auxilary function to send COM_STMT_EXECUTE packet to server and read reply.
2077
Used from cli_stmt_execute, which is in turn used by mysql_stmt_execute.
2080
static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
2082
MYSQL *mysql= stmt->mysql;
2083
NET *net= &mysql->net;
2084
uchar buff[4 /* size of stmt id */ +
2085
5 /* execution flags */];
2087
DBUG_ENTER("execute");
2088
DBUG_DUMP("packet", (uchar *) packet, length);
2090
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
2091
buff[4]= (char) stmt->flags;
2092
int4store(buff+5, 1); /* iteration count */
2094
res= test(cli_advanced_command(mysql, COM_STMT_EXECUTE, buff, sizeof(buff),
2095
(uchar*) packet, length, 1, stmt) ||
2096
(*mysql->methods->read_query_result)(mysql));
2097
stmt->affected_rows= mysql->affected_rows;
2098
stmt->server_status= mysql->server_status;
2099
stmt->insert_id= mysql->insert_id;
2102
set_stmt_errmsg(stmt, net);
2109
int cli_stmt_execute(MYSQL_STMT *stmt)
2111
DBUG_ENTER("cli_stmt_execute");
2113
if (stmt->param_count)
2115
MYSQL *mysql= stmt->mysql;
2116
NET *net= &mysql->net;
2117
MYSQL_BIND *param, *param_end;
2123
if (!stmt->bind_param_done)
2125
set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate, NULL);
2128
if (mysql->status != MYSQL_STATUS_READY ||
2129
mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
2131
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
2135
net_clear(net, 1); /* Sets net->write_pos */
2136
/* Reserve place for null-marker bytes */
2137
null_count= (stmt->param_count+7) /8;
2138
if (my_realloc_str(net, null_count + 1))
2140
set_stmt_errmsg(stmt, net);
2143
bzero((char*) net->write_pos, null_count);
2144
net->write_pos+= null_count;
2145
param_end= stmt->params + stmt->param_count;
2147
/* In case if buffers (type) altered, indicate to server */
2148
*(net->write_pos)++= (uchar) stmt->send_types_to_server;
2149
if (stmt->send_types_to_server)
2151
if (my_realloc_str(net, 2 * stmt->param_count))
2153
set_stmt_errmsg(stmt, net);
2157
Store types of parameters in first in first package
2158
that is sent to the server.
2160
for (param= stmt->params; param < param_end ; param++)
2161
store_param_type((char**) &net->write_pos, param);
2164
for (param= stmt->params; param < param_end; param++)
2166
/* check if mysql_stmt_send_long_data() was used */
2167
if (param->long_data_used)
2168
param->long_data_used= 0; /* Clear for next execute call */
2169
else if (store_param(stmt, param))
2172
length= (ulong) (net->write_pos - net->buff);
2173
/* TODO: Look into avoding the following memdup */
2174
if (!(param_data= my_memdup(net->buff, length, MYF(0))))
2176
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
2179
result= execute(stmt, param_data, length);
2180
stmt->send_types_to_server=0;
2181
my_free(param_data, MYF(MY_WME));
2182
DBUG_RETURN(result);
2184
DBUG_RETURN((int) execute(stmt,0,0));
2188
Read one row from buffered result set. Result set is created by prior
2189
call to mysql_stmt_store_result().
2191
stmt_read_row_buffered()
2194
0 - success; *row is set to valid row pointer (row data
2195
is stored in result set buffer)
2196
MYSQL_NO_DATA - end of result set. *row is set to NULL
2199
static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row)
2201
if (stmt->data_cursor)
2203
*row= (uchar *) stmt->data_cursor->data;
2204
stmt->data_cursor= stmt->data_cursor->next;
2208
return MYSQL_NO_DATA;
2212
Read one row from network: unbuffered non-cursor fetch.
2213
If last row was read, or error occured, erase this statement
2214
from record pointing to object unbuffered fetch is performed from.
2217
stmt_read_row_unbuffered()
2218
stmt statement handle
2219
row pointer to write pointer to row data;
2222
0 - success; *row contains valid address of a row;
2223
row data is stored in network buffer
2224
1 - error; error code is written to
2225
stmt->last_{errno,error}; *row is not changed
2226
MYSQL_NO_DATA - end of file was read from network;
2230
static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row)
2233
MYSQL *mysql= stmt->mysql;
2235
This function won't be called if stmt->field_count is zero
2236
or execution wasn't done: this is ensured by mysql_stmt_execute.
2240
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
2243
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2245
set_stmt_error(stmt, stmt->unbuffered_fetch_cancelled ?
2246
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
2247
unknown_sqlstate, NULL);
2250
if ((*mysql->methods->unbuffered_fetch)(mysql, (char**) row))
2252
set_stmt_errmsg(stmt, &mysql->net);
2254
If there was an error, there are no more pending rows:
2255
reset statement status to not hang up in following
2256
mysql_stmt_close (it will try to flush result set before
2257
closing the statement).
2259
mysql->status= MYSQL_STATUS_READY;
2264
mysql->status= MYSQL_STATUS_READY;
2270
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
2271
mysql->unbuffered_fetch_owner= 0;
2277
Fetch statement row using server side cursor.
2280
stmt_read_row_from_cursor()
2285
MYSQL_NO_DATA end of data
2289
stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
2291
if (stmt->data_cursor)
2292
return stmt_read_row_buffered(stmt, row);
2293
if (stmt->server_status & SERVER_STATUS_LAST_ROW_SENT)
2294
stmt->server_status &= ~SERVER_STATUS_LAST_ROW_SENT;
2297
MYSQL *mysql= stmt->mysql;
2298
NET *net= &mysql->net;
2299
MYSQL_DATA *result= &stmt->result;
2300
uchar buff[4 /* statement id */ +
2301
4 /* number of rows to fetch */];
2303
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
2306
/* Send row request to the server */
2307
int4store(buff, stmt->stmt_id);
2308
int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
2309
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
2310
buff, sizeof(buff), (uchar*) 0, 0,
2313
set_stmt_errmsg(stmt, net);
2316
if ((*mysql->methods->read_rows_from_cursor)(stmt))
2318
stmt->server_status= mysql->server_status;
2320
stmt->data_cursor= result->data;
2321
return stmt_read_row_buffered(stmt, row);
2324
return MYSQL_NO_DATA;
2329
Default read row function to not SIGSEGV in client in
2330
case of wrong sequence of API calls.
2334
stmt_read_row_no_data(MYSQL_STMT *stmt __attribute__((unused)),
2335
unsigned char **row __attribute__((unused)))
2337
return MYSQL_NO_DATA;
2341
stmt_read_row_no_result_set(MYSQL_STMT *stmt __attribute__((unused)),
2342
unsigned char **row __attribute__((unused)))
2344
set_stmt_error(stmt, CR_NO_RESULT_SET, unknown_sqlstate, NULL);
2350
Get/set statement attributes
2353
mysql_stmt_attr_get()
2354
mysql_stmt_attr_set()
2356
attr_type statement attribute
2357
value casted to const void * pointer to value.
2361
!0 wrong attribute type
2364
my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
2365
enum enum_stmt_attr_type attr_type,
2368
switch (attr_type) {
2369
case STMT_ATTR_UPDATE_MAX_LENGTH:
2370
stmt->update_max_length= value ? *(const my_bool*) value : 0;
2372
case STMT_ATTR_CURSOR_TYPE:
2375
cursor_type= value ? *(ulong*) value : 0UL;
2376
if (cursor_type > (ulong) CURSOR_TYPE_READ_ONLY)
2377
goto err_not_implemented;
2378
stmt->flags= cursor_type;
2381
case STMT_ATTR_PREFETCH_ROWS:
2383
ulong prefetch_rows= value ? *(ulong*) value : DEFAULT_PREFETCH_ROWS;
2386
stmt->prefetch_rows= prefetch_rows;
2390
goto err_not_implemented;
2393
err_not_implemented:
2394
set_stmt_error(stmt, CR_NOT_IMPLEMENTED, unknown_sqlstate, NULL);
2399
my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
2400
enum enum_stmt_attr_type attr_type,
2403
switch (attr_type) {
2404
case STMT_ATTR_UPDATE_MAX_LENGTH:
2405
*(my_bool*) value= stmt->update_max_length;
2407
case STMT_ATTR_CURSOR_TYPE:
2408
*(ulong*) value= stmt->flags;
2410
case STMT_ATTR_PREFETCH_ROWS:
2411
*(ulong*) value= stmt->prefetch_rows;
2421
Send placeholders data to server (if there are placeholders)
2422
and execute prepared statement.
2425
mysql_stmt_execute()
2426
stmt statement handle. The handle must be created
2427
with mysql_stmt_init() and prepared with
2428
mysql_stmt_prepare(). If there are placeholders
2429
in the statement they must be bound to local
2430
variables with mysql_stmt_bind_param().
2433
This function will automatically flush pending result
2434
set (if there is one), send parameters data to the server
2435
and read result of statement execution.
2436
If previous result set was cached with mysql_stmt_store_result()
2437
it will also be freed in the beginning of this call.
2438
The server can return 3 types of responses to this command:
2439
- error, can be retrieved with mysql_stmt_error()
2440
- ok, no result set pending. In this case we just update
2441
stmt->insert_id and stmt->affected_rows.
2442
- the query returns a result set: there could be 0 .. N
2443
rows in it. In this case the server can also send updated
2444
result set metadata.
2446
Next steps you may want to make:
2447
- find out if there is result set with mysql_stmt_field_count().
2449
- optionally, cache entire result set on client to unblock
2450
connection with mysql_stmt_store_result()
2451
- bind client variables to result set columns and start read rows
2452
with mysql_stmt_fetch().
2453
- reset statement with mysql_stmt_reset() or close it with
2456
- find out last insert id and number of affected rows with
2457
mysql_stmt_insert_id(), mysql_stmt_affected_rows()
2461
1 error, message can be retrieved with mysql_stmt_error().
2464
int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
2466
MYSQL *mysql= stmt->mysql;
2467
DBUG_ENTER("mysql_stmt_execute");
2471
/* Error is already set in mysql_detatch_stmt_list */
2475
if (reset_stmt_handle(stmt, RESET_STORE_RESULT))
2478
No need to check for stmt->state: if the statement wasn't
2479
prepared we'll get 'unknown statement handler' error from server.
2481
if (mysql->methods->stmt_execute(stmt))
2483
if (mysql->field_count)
2485
/* Server has sent result set metadata */
2486
if (stmt->field_count == 0)
2489
This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
2490
prepared statements can't send result set metadata for these queries
2491
on prepare stage. Read it now.
2493
alloc_stmt_fields(stmt);
2498
Update result set metadata if it for some reason changed between
2499
prepare and execute, i.e.:
2500
- in case of 'SELECT ?' we don't know column type unless data was
2501
supplied to mysql_stmt_execute, so updated column type is sent
2503
- if data dictionary changed between prepare and execute, for
2504
example a table used in the query was altered.
2505
Note, that now (4.1.3) we always send metadata in reply to
2506
COM_STMT_EXECUTE (even if it is not necessary), so either this or
2507
previous branch always works.
2508
TODO: send metadata only when it's really necessary and add a warning
2509
'Metadata changed' when it's sent twice.
2511
update_stmt_fields(stmt);
2514
stmt->state= MYSQL_STMT_EXECUTE_DONE;
2515
if (stmt->field_count)
2517
if (stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
2519
mysql->status= MYSQL_STATUS_READY;
2520
stmt->read_row_func= stmt_read_row_from_cursor;
2522
else if (stmt->flags & CURSOR_TYPE_READ_ONLY)
2525
This is a single-row result set, a result set with no rows, EXPLAIN,
2526
SHOW VARIABLES, or some other command which either a) bypasses the
2527
cursors framework in the server and writes rows directly to the
2528
network or b) is more efficient if all (few) result set rows are
2529
precached on client and server's resources are freed.
2531
DBUG_RETURN(mysql_stmt_store_result(stmt));
2535
stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled;
2536
stmt->unbuffered_fetch_cancelled= FALSE;
2537
stmt->read_row_func= stmt_read_row_unbuffered;
2545
Return total parameters count in the statement
2548
ulong STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt)
2550
DBUG_ENTER("mysql_stmt_param_count");
2551
DBUG_RETURN(stmt->param_count);
2555
Return total affected rows from the last statement
2558
my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt)
2560
return stmt->affected_rows;
2565
Returns the number of result columns for the most recent query
2566
run on this statement.
2569
unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt)
2571
return stmt->field_count;
2575
Return last inserted id for auto_increment columns.
2578
mysql_stmt_insert_id()
2579
stmt statement handle
2582
Current implementation of this call has a caveat: stmt->insert_id is
2583
unconditionally updated from mysql->insert_id in the end of each
2584
mysql_stmt_execute(). This works OK if mysql->insert_id contains new
2585
value (sent in reply to mysql_stmt_execute()), otherwise stmt->insert_id
2586
value gets undefined, as it's updated from some arbitrary value saved in
2587
connection structure during some other call.
2590
my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt)
2592
return stmt->insert_id;
2596
static my_bool int_is_null_true= 1; /* Used for MYSQL_TYPE_NULL */
2597
static my_bool int_is_null_false= 0;
2601
Set up input data buffers for a statement.
2604
mysql_stmt_bind_param()
2605
stmt statement handle
2606
The statement must be prepared with mysql_stmt_prepare().
2607
my_bind Array of mysql_stmt_param_count() bind parameters.
2608
This function doesn't check that size of this argument
2609
is >= mysql_stmt_field_count(): it's user's responsibility.
2612
Use this call after mysql_stmt_prepare() to bind user variables to
2614
Each element of bind array stands for a placeholder. Placeholders
2615
are counted from 0. For example statement
2616
'INSERT INTO t (a, b) VALUES (?, ?)'
2617
contains two placeholders, and for such statement you should supply
2618
bind array of two elements (MYSQL_BIND bind[2]).
2620
By properly initializing bind array you can bind virtually any
2621
C language type to statement's placeholders:
2622
First, it's strongly recommended to always zero-initialize entire
2623
bind structure before setting its members. This will both shorten
2624
your application code and make it robust to future extensions of
2625
MYSQL_BIND structure.
2626
Then you need to assign typecode of your application buffer to
2627
MYSQL_BIND::buffer_type. The following typecodes with their
2628
correspondence to C language types are supported:
2629
MYSQL_TYPE_TINY for 8-bit integer variables. Normally it's
2630
'signed char' and 'unsigned char';
2631
MYSQL_TYPE_SHORT for 16-bit signed and unsigned variables. This
2632
is usually 'short' and 'unsigned short';
2633
MYSQL_TYPE_LONG for 32-bit signed and unsigned variables. It
2634
corresponds to 'int' and 'unsigned int' on
2635
vast majority of platforms. On IA-32 and some
2636
other 32-bit systems you can also use 'long'
2638
MYSQL_TYPE_LONGLONG 64-bit signed or unsigned integer. Stands for
2639
'[unsigned] long long' on most platforms;
2640
MYSQL_TYPE_FLOAT 32-bit floating point type, 'float' on most
2642
MYSQL_TYPE_DOUBLE 64-bit floating point type, 'double' on most
2644
MYSQL_TYPE_TIME broken-down time stored in MYSQL_TIME
2646
MYSQL_TYPE_DATE date stored in MYSQL_TIME structure
2647
MYSQL_TYPE_DATETIME datetime stored in MYSQL_TIME structure See
2648
more on how to use these types for sending
2649
dates and times below;
2650
MYSQL_TYPE_STRING character string, assumed to be in
2651
character-set-client. If character set of
2652
client is not equal to character set of
2653
column, value for this placeholder will be
2654
converted to destination character set before
2656
MYSQL_TYPE_BLOB sequence of bytes. This sequence is assumed to
2657
be in binary character set (which is the same
2658
as no particular character set), and is never
2659
converted to any other character set. See also
2660
notes about supplying string/blob length
2662
MYSQL_TYPE_NULL special typecode for binding nulls.
2663
These C/C++ types are not supported yet by the API: long double,
2666
As you can see from the list above, it's responsibility of
2667
application programmer to ensure that chosen typecode properly
2668
corresponds to host language type. For example on all platforms
2669
where we build MySQL packages (as of MySQL 4.1.4) int is a 32-bit
2670
type. So for int you can always assume that proper typecode is
2671
MYSQL_TYPE_LONG (however queer it sounds, the name is legacy of the
2672
old MySQL API). In contrary sizeof(long) can be 4 or 8 8-bit bytes,
2673
depending on platform.
2675
TODO: provide client typedefs for each integer and floating point
2676
typecode, i. e. int8, uint8, float32, etc.
2678
Once typecode was set, it's necessary to assign MYSQL_BIND::buffer
2679
to point to the buffer of given type. Finally, additional actions
2680
may be taken for some types or use cases:
2682
Binding integer types.
2683
For integer types you might also need to set MYSQL_BIND::is_unsigned
2684
member. Set it to TRUE when binding unsigned char, unsigned short,
2685
unsigned int, unsigned long, unsigned long long.
2687
Binding floating point types.
2688
For floating point types you just need to set
2689
MYSQL_BIND::buffer_type and MYSQL_BIND::buffer. The rest of the
2690
members should be zero-initialized.
2693
You might have a column always NULL, never NULL, or sometimes
2694
NULL. For an always NULL column set MYSQL_BIND::buffer_type to
2695
MYSQL_TYPE_NULL. The rest of the members just need to be
2696
zero-initialized. For never NULL columns set
2697
MYSQL_BIND::is_null to 0, or this has already been done if you
2698
zero-initialized the entire structure. If you set
2699
MYSQL_TYPE::is_null to point to an application buffer of type
2700
'my_bool', then this buffer will be checked on each execution:
2701
this way you can set the buffer to TRUE, or any non-0 value for
2702
NULLs, and to FALSE or 0 for not NULL data.
2704
Binding text strings and sequences of bytes.
2705
For strings, in addition to MYSQL_BIND::buffer_type and
2706
MYSQL_BIND::buffer you need to set MYSQL_BIND::length or
2707
MYSQL_BIND::buffer_length. If 'length' is set, 'buffer_length'
2708
is ignored. 'buffer_length' member should be used when size of
2709
string doesn't change between executions. If you want to vary
2710
buffer length for each value, set 'length' to point to an
2711
application buffer of type 'unsigned long' and set this long to
2712
length of the string before each mysql_stmt_execute().
2714
Binding dates and times.
2715
For binding dates and times prepared statements API provides
2716
clients with MYSQL_TIME structure. A pointer to instance of this
2717
structure should be assigned to MYSQL_BIND::buffer whenever
2718
MYSQL_TYPE_TIME, MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME typecodes
2719
are used. When typecode is MYSQL_TYPE_TIME, only members
2720
'hour', 'minute', 'second' and 'neg' (is time offset negative)
2721
are used. These members only will be sent to the server.
2722
MYSQL_TYPE_DATE implies use of 'year', 'month', 'day', 'neg'.
2723
MYSQL_TYPE_DATETIME utilizes both parts of MYSQL_TIME structure.
2724
You don't have to set MYSQL_TIME::time_type member: it's not
2725
used when sending data to the server, typecode information is
2726
enough. 'second_part' member can hold microsecond precision of
2727
time value, but now it's only supported on protocol level: you
2728
can't store microsecond in a column, or use in temporal
2729
calculations. However, if you send a time value with microsecond
2730
part for 'SELECT ?', statement, you'll get it back unchanged
2734
If conversion from host language type to data representation,
2735
corresponding to SQL type, is required it's done on the server.
2736
Data truncation is possible when conversion is lossy. For
2737
example, if you supply MYSQL_TYPE_DATETIME value out of valid
2738
SQL type TIMESTAMP range, the same conversion will be applied as
2739
if this value would have been sent as string in the old
2740
protocol. TODO: document how the server will behave in case of
2741
truncation/data loss.
2743
After variables were bound, you can repeatedly set/change their
2744
values and mysql_stmt_execute() the statement.
2746
See also: mysql_stmt_send_long_data() for sending long text/blob
2747
data in pieces, examples in tests/mysql_client_test.c.
2748
Next steps you might want to make:
2749
- execute statement with mysql_stmt_execute(),
2750
- reset statement using mysql_stmt_reset() or reprepare it with
2751
another query using mysql_stmt_prepare()
2752
- close statement with mysql_stmt_close().
2755
The function copies given bind array to internal storage of the
2756
statement, and sets up typecode-specific handlers to perform
2757
serialization of bound data. This means that although you don't need
2758
to call this routine after each assignment to bind buffers, you
2759
need to call it each time you change parameter typecodes, or other
2760
members of MYSQL_BIND array.
2761
This is a pure local call. Data types of client buffers are sent
2762
along with buffers' data at first execution of the statement.
2766
1 error, can be retrieved with mysql_stmt_error.
2769
my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *my_bind)
2772
MYSQL_BIND *param, *end;
2773
DBUG_ENTER("mysql_stmt_bind_param");
2775
if (!stmt->param_count)
2777
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
2779
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate, NULL);
2785
/* Allocated on prepare */
2786
memcpy((char*) stmt->params, (char*) my_bind,
2787
sizeof(MYSQL_BIND) * stmt->param_count);
2789
for (param= stmt->params, end= param+stmt->param_count;
2793
param->param_number= count++;
2794
param->long_data_used= 0;
2796
/* If param->is_null is not set, then the value can never be NULL */
2797
if (!param->is_null)
2798
param->is_null= &int_is_null_false;
2800
/* Setup data copy functions for the different supported types */
2801
switch (param->buffer_type) {
2802
case MYSQL_TYPE_NULL:
2803
param->is_null= &int_is_null_true;
2805
case MYSQL_TYPE_TINY:
2806
/* Force param->length as this is fixed for this type */
2807
param->length= ¶m->buffer_length;
2808
param->buffer_length= 1;
2809
param->store_param_func= store_param_tinyint;
2811
case MYSQL_TYPE_SHORT:
2812
param->length= ¶m->buffer_length;
2813
param->buffer_length= 2;
2814
param->store_param_func= store_param_short;
2816
case MYSQL_TYPE_LONG:
2817
param->length= ¶m->buffer_length;
2818
param->buffer_length= 4;
2819
param->store_param_func= store_param_int32;
2821
case MYSQL_TYPE_LONGLONG:
2822
param->length= ¶m->buffer_length;
2823
param->buffer_length= 8;
2824
param->store_param_func= store_param_int64;
2826
case MYSQL_TYPE_FLOAT:
2827
param->length= ¶m->buffer_length;
2828
param->buffer_length= 4;
2829
param->store_param_func= store_param_float;
2831
case MYSQL_TYPE_DOUBLE:
2832
param->length= ¶m->buffer_length;
2833
param->buffer_length= 8;
2834
param->store_param_func= store_param_double;
2836
case MYSQL_TYPE_TIME:
2837
param->store_param_func= store_param_time;
2838
param->buffer_length= MAX_TIME_REP_LENGTH;
2840
case MYSQL_TYPE_DATE:
2841
param->store_param_func= store_param_date;
2842
param->buffer_length= MAX_DATE_REP_LENGTH;
2844
case MYSQL_TYPE_DATETIME:
2845
case MYSQL_TYPE_TIMESTAMP:
2846
param->store_param_func= store_param_datetime;
2847
param->buffer_length= MAX_DATETIME_REP_LENGTH;
2849
case MYSQL_TYPE_TINY_BLOB:
2850
case MYSQL_TYPE_MEDIUM_BLOB:
2851
case MYSQL_TYPE_LONG_BLOB:
2852
case MYSQL_TYPE_BLOB:
2853
case MYSQL_TYPE_VARCHAR:
2854
case MYSQL_TYPE_VAR_STRING:
2855
case MYSQL_TYPE_STRING:
2856
case MYSQL_TYPE_DECIMAL:
2857
case MYSQL_TYPE_NEWDECIMAL:
2858
param->store_param_func= store_param_str;
2860
For variable length types user must set either length or
2865
strmov(stmt->sqlstate, unknown_sqlstate);
2866
sprintf(stmt->last_error,
2867
ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
2868
param->buffer_type, count);
2872
If param->length is not given, change it to point to buffer_length.
2873
This way we can always use *param->length to get the length of data
2876
param->length= ¶m->buffer_length;
2878
/* We have to send/resend type information to MySQL */
2879
stmt->send_types_to_server= TRUE;
2880
stmt->bind_param_done= TRUE;
2885
/********************************************************************
2886
Long data implementation
2887
*********************************************************************/
2890
Send long data in pieces to the server
2893
mysql_stmt_send_long_data()
2894
stmt Statement handler
2895
param_number Parameter number (0 - N-1)
2896
data Data to send to server
2897
length Length of data to send (may be 0)
2900
This call can be used repeatedly to send long data in pieces
2901
for any string/binary placeholder. Data supplied for
2902
a placeholder is saved at server side till execute, and then
2903
used instead of value from MYSQL_BIND object. More precisely,
2904
if long data for a parameter was supplied, MYSQL_BIND object
2905
corresponding to this parameter is not sent to server. In the
2906
end of execution long data states of placeholders are reset,
2907
so next time values of such placeholders will be taken again
2908
from MYSQL_BIND array.
2909
The server does not reply to this call: if there was an error
2910
in data handling (which now only can happen if server run out
2911
of memory) it would be returned in reply to
2912
mysql_stmt_execute().
2913
You should choose type of long data carefully if you care
2914
about character set conversions performed by server when the
2915
statement is executed. No conversion is performed at all for
2916
MYSQL_TYPE_BLOB and other binary typecodes. For
2917
MYSQL_TYPE_STRING and the rest of text placeholders data is
2918
converted from client character set to character set of
2919
connection. If these character sets are different, this
2920
conversion may require additional memory at server, equal to
2921
total size of supplied pieces.
2929
mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
2930
const char *data, ulong length)
2933
DBUG_ENTER("mysql_stmt_send_long_data");
2934
DBUG_ASSERT(stmt != 0);
2935
DBUG_PRINT("enter",("param no: %d data: 0x%lx, length : %ld",
2936
param_number, (long) data, length));
2939
We only need to check for stmt->param_count, if it's not null
2942
if (param_number >= stmt->param_count)
2944
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate, NULL);
2948
param= stmt->params+param_number;
2949
if (!IS_LONGDATA(param->buffer_type))
2951
/* Long data handling should be used only for string/binary types */
2952
strmov(stmt->sqlstate, unknown_sqlstate);
2953
sprintf(stmt->last_error, ER(stmt->last_errno= CR_INVALID_BUFFER_USE),
2954
param->param_number);
2959
Send long data packet if there is data or we're sending long data
2962
if (length || param->long_data_used == 0)
2964
MYSQL *mysql= stmt->mysql;
2965
/* Packet header: stmt id (4 bytes), param no (2 bytes) */
2966
uchar buff[MYSQL_LONG_DATA_HEADER];
2968
int4store(buff, stmt->stmt_id);
2969
int2store(buff + 4, param_number);
2970
param->long_data_used= 1;
2973
Note that we don't get any ok packet from the server in this case
2974
This is intentional to save bandwidth.
2976
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_SEND_LONG_DATA,
2977
buff, sizeof(buff), (uchar*) data,
2980
set_stmt_errmsg(stmt, &mysql->net);
2988
/********************************************************************
2989
Fetch and conversion of result set rows (binary protocol).
2990
*********************************************************************/
2993
Read date, (time, datetime) value from network buffer and store it
2994
in MYSQL_TIME structure.
2997
read_binary_{date,time,datetime}()
2998
tm MYSQL_TIME structure to fill
2999
pos pointer to current position in network buffer.
3000
These functions increase pos to point to the beginning of the
3003
Auxiliary functions to read time (date, datetime) values from network
3004
buffer and store in MYSQL_TIME structure. Jointly used by conversion
3005
and no-conversion fetching.
3008
static void read_binary_time(MYSQL_TIME *tm, uchar **pos)
3010
/* net_field_length will set pos to the first byte of data */
3011
uint length= net_field_length(pos);
3018
tm->day= (ulong) sint4korr(to+1);
3019
tm->hour= (uint) to[5];
3020
tm->minute= (uint) to[6];
3021
tm->second= (uint) to[7];
3022
tm->second_part= (length > 8) ? (ulong) sint4korr(to+8) : 0;
3023
tm->year= tm->month= 0;
3026
/* Convert days to hours at once */
3027
tm->hour+= tm->day*24;
3030
tm->time_type= MYSQL_TIMESTAMP_TIME;
3035
set_zero_time(tm, MYSQL_TIMESTAMP_TIME);
3038
static void read_binary_datetime(MYSQL_TIME *tm, uchar **pos)
3040
uint length= net_field_length(pos);
3047
tm->year= (uint) sint2korr(to);
3048
tm->month= (uint) to[2];
3049
tm->day= (uint) to[3];
3053
tm->hour= (uint) to[4];
3054
tm->minute= (uint) to[5];
3055
tm->second= (uint) to[6];
3058
tm->hour= tm->minute= tm->second= 0;
3059
tm->second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0;
3060
tm->time_type= MYSQL_TIMESTAMP_DATETIME;
3065
set_zero_time(tm, MYSQL_TIMESTAMP_DATETIME);
3068
static void read_binary_date(MYSQL_TIME *tm, uchar **pos)
3070
uint length= net_field_length(pos);
3075
tm->year = (uint) sint2korr(to);
3076
tm->month= (uint) to[2];
3077
tm->day= (uint) to[3];
3079
tm->hour= tm->minute= tm->second= 0;
3082
tm->time_type= MYSQL_TIMESTAMP_DATE;
3087
set_zero_time(tm, MYSQL_TIMESTAMP_DATE);
3092
Convert string to supplied buffer of any type.
3095
fetch_string_with_conversion()
3096
param output buffer descriptor
3101
static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
3104
char *buffer= (char *)param->buffer;
3106
char *endptr= value + length;
3109
This function should support all target buffer types: the rest
3110
of conversion functions can delegate conversion to it.
3112
switch (param->buffer_type) {
3113
case MYSQL_TYPE_NULL: /* do nothing */
3115
case MYSQL_TYPE_TINY:
3117
longlong data= my_strtoll10(value, &endptr, &err);
3118
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
3119
INT_MIN8, INT_MAX8, UINT_MAX8) || err > 0);
3120
*buffer= (uchar) data;
3123
case MYSQL_TYPE_SHORT:
3125
longlong data= my_strtoll10(value, &endptr, &err);
3126
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
3127
INT_MIN16, INT_MAX16, UINT_MAX16) || err > 0);
3128
shortstore(buffer, (short) data);
3131
case MYSQL_TYPE_LONG:
3133
longlong data= my_strtoll10(value, &endptr, &err);
3134
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
3135
INT_MIN32, INT_MAX32, UINT_MAX32) || err > 0);
3136
longstore(buffer, (int32) data);
3139
case MYSQL_TYPE_LONGLONG:
3141
longlong data= my_strtoll10(value, &endptr, &err);
3142
*param->error= param->is_unsigned ? err != 0 :
3143
(err > 0 || (err == 0 && data < 0));
3144
longlongstore(buffer, data);
3147
case MYSQL_TYPE_FLOAT:
3149
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
3150
float fdata= (float) data;
3151
*param->error= (fdata != data) | test(err);
3152
floatstore(buffer, fdata);
3155
case MYSQL_TYPE_DOUBLE:
3157
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
3158
*param->error= test(err);
3159
doublestore(buffer, data);
3162
case MYSQL_TYPE_TIME:
3164
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
3165
str_to_time(value, length, tm, &err);
3166
*param->error= test(err);
3169
case MYSQL_TYPE_DATE:
3170
case MYSQL_TYPE_DATETIME:
3171
case MYSQL_TYPE_TIMESTAMP:
3173
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
3174
(void) str_to_datetime(value, length, tm, TIME_FUZZY_DATE, &err);
3175
*param->error= test(err) && (param->buffer_type == MYSQL_TYPE_DATE &&
3176
tm->time_type != MYSQL_TIMESTAMP_DATE);
3179
case MYSQL_TYPE_TINY_BLOB:
3180
case MYSQL_TYPE_MEDIUM_BLOB:
3181
case MYSQL_TYPE_LONG_BLOB:
3182
case MYSQL_TYPE_BLOB:
3183
case MYSQL_TYPE_DECIMAL:
3184
case MYSQL_TYPE_NEWDECIMAL:
3188
Copy column data to the buffer taking into account offset,
3189
data length and buffer length.
3191
char *start= value + param->offset;
3192
char *end= value + length;
3196
copy_length= end - start;
3197
/* We've got some data beyond offset: copy up to buffer_length bytes */
3198
if (param->buffer_length)
3199
memcpy(buffer, start, min(copy_length, param->buffer_length));
3203
if (copy_length < param->buffer_length)
3204
buffer[copy_length]= '\0';
3205
*param->error= copy_length > param->buffer_length;
3207
param->length will always contain length of entire column;
3208
number of copied bytes may be way different:
3210
*param->length= length;
3218
Convert integer value to client buffer of any type.
3221
fetch_long_with_conversion()
3222
param output buffer descriptor
3223
field column metadata
3227
static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
3228
longlong value, my_bool is_unsigned)
3230
char *buffer= (char *)param->buffer;
3232
switch (param->buffer_type) {
3233
case MYSQL_TYPE_NULL: /* do nothing */
3235
case MYSQL_TYPE_TINY:
3236
*param->error= IS_TRUNCATED(value, param->is_unsigned,
3237
INT_MIN8, INT_MAX8, UINT_MAX8);
3238
*(uchar *)param->buffer= (uchar) value;
3240
case MYSQL_TYPE_SHORT:
3241
*param->error= IS_TRUNCATED(value, param->is_unsigned,
3242
INT_MIN16, INT_MAX16, UINT_MAX16);
3243
shortstore(buffer, (short) value);
3245
case MYSQL_TYPE_LONG:
3246
*param->error= IS_TRUNCATED(value, param->is_unsigned,
3247
INT_MIN32, INT_MAX32, UINT_MAX32);
3248
longstore(buffer, (int32) value);
3250
case MYSQL_TYPE_LONGLONG:
3251
longlongstore(buffer, value);
3252
*param->error= param->is_unsigned != is_unsigned && value < 0;
3254
case MYSQL_TYPE_FLOAT:
3257
We need to mark the local variable volatile to
3258
workaround Intel FPU executive precision feature.
3259
(See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details)
3261
volatile float data;
3264
data= (float) ulonglong2double(value);
3265
*param->error= ((ulonglong) value) != ((ulonglong) data);
3270
*param->error= value != ((longlong) data);
3272
floatstore(buffer, data);
3275
case MYSQL_TYPE_DOUBLE:
3277
volatile double data;
3280
data= ulonglong2double(value);
3281
*param->error= ((ulonglong) value) != ((ulonglong) data);
3285
data= (double)value;
3286
*param->error= value != ((longlong) data);
3288
doublestore(buffer, data);
3291
case MYSQL_TYPE_TIME:
3292
case MYSQL_TYPE_DATE:
3293
case MYSQL_TYPE_TIMESTAMP:
3294
case MYSQL_TYPE_DATETIME:
3297
value= number_to_datetime(value, (MYSQL_TIME *) buffer, TIME_FUZZY_DATE,
3299
*param->error= test(error);
3304
uchar buff[22]; /* Enough for longlong */
3305
uchar *end= (uchar*) longlong10_to_str(value, (char*) buff,
3306
is_unsigned ? 10: -10);
3307
/* Resort to string conversion which supports all typecodes */
3308
uint length= (uint) (end-buff);
3310
if (field->flags & ZEROFILL_FLAG && length < field->length &&
3313
bmove_upp(buff+field->length,buff+length, length);
3314
bfill(buff, field->length - length,'0');
3315
length= field->length;
3317
fetch_string_with_conversion(param, (char*) buff, length);
3324
Convert double/float column to supplied buffer of any type.
3327
fetch_float_with_conversion()
3328
param output buffer descriptor
3329
field column metadata
3331
type either MY_GCVT_ARG_FLOAT or MY_GCVT_ARG_DOUBLE.
3332
Affects the maximum number of significant digits
3333
returned by my_gcvt().
3336
static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
3337
double value, my_gcvt_arg_type type)
3339
char *buffer= (char *)param->buffer;
3340
double val64 = (value < 0 ? -floor(-value) : floor(value));
3342
switch (param->buffer_type) {
3343
case MYSQL_TYPE_NULL: /* do nothing */
3345
case MYSQL_TYPE_TINY:
3347
We need to _store_ data in the buffer before the truncation check to
3348
workaround Intel FPU executive precision feature.
3349
(See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details)
3350
Sic: AFAIU it does not guarantee to work.
3352
if (param->is_unsigned)
3353
*buffer= (uint8) value;
3355
*buffer= (int8) value;
3356
*param->error= val64 != (param->is_unsigned ? (double)((uint8) *buffer) :
3357
(double)((int8) *buffer));
3359
case MYSQL_TYPE_SHORT:
3360
if (param->is_unsigned)
3362
ushort data= (ushort) value;
3363
shortstore(buffer, data);
3367
short data= (short) value;
3368
shortstore(buffer, data);
3370
*param->error= val64 != (param->is_unsigned ? (double) (*(ushort*) buffer):
3371
(double) (*(short*) buffer));
3373
case MYSQL_TYPE_LONG:
3374
if (param->is_unsigned)
3376
uint32 data= (uint32) value;
3377
longstore(buffer, data);
3381
int32 data= (int32) value;
3382
longstore(buffer, data);
3384
*param->error= val64 != (param->is_unsigned ? (double) (*(uint32*) buffer):
3385
(double) (*(int32*) buffer));
3387
case MYSQL_TYPE_LONGLONG:
3388
if (param->is_unsigned)
3390
ulonglong data= (ulonglong) value;
3391
longlongstore(buffer, data);
3395
longlong data= (longlong) value;
3396
longlongstore(buffer, data);
3398
*param->error= val64 != (param->is_unsigned ?
3399
ulonglong2double(*(ulonglong*) buffer) :
3400
(double) (*(longlong*) buffer));
3402
case MYSQL_TYPE_FLOAT:
3404
float data= (float) value;
3405
floatstore(buffer, data);
3406
*param->error= (*(float*) buffer) != value;
3409
case MYSQL_TYPE_DOUBLE:
3411
doublestore(buffer, value);
3417
Resort to fetch_string_with_conversion: this should handle
3418
floating point -> string conversion nicely, honor all typecodes
3419
and param->offset possibly set in mysql_stmt_fetch_column
3421
char buff[FLOATING_POINT_BUFFER];
3423
if (field->decimals >= NOT_FIXED_DEC)
3424
len= my_gcvt(value, type,
3425
(int) min(sizeof(buff)-1, param->buffer_length),
3428
len= my_fcvt(value, (int) field->decimals, buff, NULL);
3430
if (field->flags & ZEROFILL_FLAG && len < field->length &&
3431
field->length < MAX_DOUBLE_STRING_REP_LENGTH - 1)
3433
bmove_upp((uchar*) buff + field->length, (uchar*) buff + len,
3435
bfill((char*) buff, field->length - len, '0');
3438
fetch_string_with_conversion(param, buff, len);
3447
Fetch time/date/datetime to supplied buffer of any type
3450
param output buffer descriptor
3454
static void fetch_datetime_with_conversion(MYSQL_BIND *param,
3456
MYSQL_TIME *my_time)
3458
switch (param->buffer_type) {
3459
case MYSQL_TYPE_NULL: /* do nothing */
3461
case MYSQL_TYPE_DATE:
3462
*(MYSQL_TIME *)(param->buffer)= *my_time;
3463
*param->error= my_time->time_type != MYSQL_TIMESTAMP_DATE;
3465
case MYSQL_TYPE_TIME:
3466
*(MYSQL_TIME *)(param->buffer)= *my_time;
3467
*param->error= my_time->time_type != MYSQL_TIMESTAMP_TIME;
3469
case MYSQL_TYPE_DATETIME:
3470
case MYSQL_TYPE_TIMESTAMP:
3471
*(MYSQL_TIME *)(param->buffer)= *my_time;
3472
/* No error: time and date are compatible with datetime */
3474
case MYSQL_TYPE_YEAR:
3475
shortstore(param->buffer, my_time->year);
3478
case MYSQL_TYPE_FLOAT:
3479
case MYSQL_TYPE_DOUBLE:
3481
ulonglong value= TIME_to_ulonglong(my_time);
3482
fetch_float_with_conversion(param, field,
3483
ulonglong2double(value), MY_GCVT_ARG_DOUBLE);
3486
case MYSQL_TYPE_TINY:
3487
case MYSQL_TYPE_SHORT:
3488
case MYSQL_TYPE_INT24:
3489
case MYSQL_TYPE_LONG:
3490
case MYSQL_TYPE_LONGLONG:
3492
longlong value= (longlong) TIME_to_ulonglong(my_time);
3493
fetch_long_with_conversion(param, field, value, TRUE);
3499
Convert time value to string and delegate the rest to
3500
fetch_string_with_conversion:
3502
char buff[MAX_DATE_STRING_REP_LENGTH];
3503
uint length= my_TIME_to_str(my_time, buff);
3504
/* Resort to string conversion */
3505
fetch_string_with_conversion(param, (char *)buff, length);
3513
Fetch and convert result set column to output buffer.
3516
fetch_result_with_conversion()
3517
param output buffer descriptor
3518
field column metadata
3519
row points to a column of result set tuple in binary format
3522
This is a fallback implementation of column fetch used
3523
if column and output buffer types do not match.
3524
Increases tuple pointer to point at the next column within the
3528
static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
3531
enum enum_field_types field_type= field->type;
3532
uint field_is_unsigned= field->flags & UNSIGNED_FLAG;
3534
switch (field_type) {
3535
case MYSQL_TYPE_TINY:
3538
/* sic: we need to cast to 'signed char' as 'char' may be unsigned */
3539
longlong data= field_is_unsigned ? (longlong) value :
3540
(longlong) (signed char) value;
3541
fetch_long_with_conversion(param, field, data, 0);
3545
case MYSQL_TYPE_SHORT:
3546
case MYSQL_TYPE_YEAR:
3548
short value= sint2korr(*row);
3549
longlong data= field_is_unsigned ? (longlong) (unsigned short) value :
3551
fetch_long_with_conversion(param, field, data, 0);
3555
case MYSQL_TYPE_INT24: /* mediumint is sent as 4 bytes int */
3556
case MYSQL_TYPE_LONG:
3558
int32 value= sint4korr(*row);
3559
longlong data= field_is_unsigned ? (longlong) (uint32) value :
3561
fetch_long_with_conversion(param, field, data, 0);
3565
case MYSQL_TYPE_LONGLONG:
3567
longlong value= (longlong)sint8korr(*row);
3568
fetch_long_with_conversion(param, field, value,
3569
field->flags & UNSIGNED_FLAG);
3573
case MYSQL_TYPE_FLOAT:
3576
float4get(value,*row);
3577
fetch_float_with_conversion(param, field, value, MY_GCVT_ARG_FLOAT);
3581
case MYSQL_TYPE_DOUBLE:
3584
float8get(value,*row);
3585
fetch_float_with_conversion(param, field, value, MY_GCVT_ARG_DOUBLE);
3589
case MYSQL_TYPE_DATE:
3593
read_binary_date(&tm, row);
3594
fetch_datetime_with_conversion(param, field, &tm);
3597
case MYSQL_TYPE_TIME:
3601
read_binary_time(&tm, row);
3602
fetch_datetime_with_conversion(param, field, &tm);
3605
case MYSQL_TYPE_DATETIME:
3606
case MYSQL_TYPE_TIMESTAMP:
3610
read_binary_datetime(&tm, row);
3611
fetch_datetime_with_conversion(param, field, &tm);
3616
ulong length= net_field_length(row);
3617
fetch_string_with_conversion(param, (char*) *row, length);
3626
Functions to fetch data to application buffers without conversion.
3628
All functions have the following characteristics:
3632
param MySQL bind param
3636
These are no-conversion functions, used in binary protocol to store
3637
rows in application buffers. A function used only if type of binary data
3638
is compatible with type of application buffer.
3644
static void fetch_result_tinyint(MYSQL_BIND *param, MYSQL_FIELD *field,
3647
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3649
*(uchar *)param->buffer= data;
3650
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX8;
3654
static void fetch_result_short(MYSQL_BIND *param, MYSQL_FIELD *field,
3657
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3658
ushort data= (ushort) sint2korr(*row);
3659
shortstore(param->buffer, data);
3660
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX16;
3664
static void fetch_result_int32(MYSQL_BIND *param,
3665
MYSQL_FIELD *field __attribute__((unused)),
3668
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3669
uint32 data= (uint32) sint4korr(*row);
3670
longstore(param->buffer, data);
3671
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX32;
3675
static void fetch_result_int64(MYSQL_BIND *param,
3676
MYSQL_FIELD *field __attribute__((unused)),
3679
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3680
ulonglong data= (ulonglong) sint8korr(*row);
3681
*param->error= param->is_unsigned != field_is_unsigned && data > LONGLONG_MAX;
3682
longlongstore(param->buffer, data);
3686
static void fetch_result_float(MYSQL_BIND *param,
3687
MYSQL_FIELD *field __attribute__((unused)),
3691
float4get(value,*row);
3692
floatstore(param->buffer, value);
3696
static void fetch_result_double(MYSQL_BIND *param,
3697
MYSQL_FIELD *field __attribute__((unused)),
3701
float8get(value,*row);
3702
doublestore(param->buffer, value);
3706
static void fetch_result_time(MYSQL_BIND *param,
3707
MYSQL_FIELD *field __attribute__((unused)),
3710
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
3711
read_binary_time(tm, row);
3714
static void fetch_result_date(MYSQL_BIND *param,
3715
MYSQL_FIELD *field __attribute__((unused)),
3718
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
3719
read_binary_date(tm, row);
3722
static void fetch_result_datetime(MYSQL_BIND *param,
3723
MYSQL_FIELD *field __attribute__((unused)),
3726
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
3727
read_binary_datetime(tm, row);
3730
static void fetch_result_bin(MYSQL_BIND *param,
3731
MYSQL_FIELD *field __attribute__((unused)),
3734
ulong length= net_field_length(row);
3735
ulong copy_length= min(length, param->buffer_length);
3736
memcpy(param->buffer, (char *)*row, copy_length);
3737
*param->length= length;
3738
*param->error= copy_length < length;
3742
static void fetch_result_str(MYSQL_BIND *param,
3743
MYSQL_FIELD *field __attribute__((unused)),
3746
ulong length= net_field_length(row);
3747
ulong copy_length= min(length, param->buffer_length);
3748
memcpy(param->buffer, (char *)*row, copy_length);
3749
/* Add an end null if there is room in the buffer */
3750
if (copy_length != param->buffer_length)
3751
((uchar *)param->buffer)[copy_length]= '\0';
3752
*param->length= length; /* return total length */
3753
*param->error= copy_length < length;
3759
functions to calculate max lengths for strings during
3760
mysql_stmt_store_result()
3763
static void skip_result_fixed(MYSQL_BIND *param,
3764
MYSQL_FIELD *field __attribute__((unused)),
3768
(*row)+= param->pack_length;
3772
static void skip_result_with_length(MYSQL_BIND *param __attribute__((unused)),
3773
MYSQL_FIELD *field __attribute__((unused)),
3777
ulong length= net_field_length(row);
3782
static void skip_result_string(MYSQL_BIND *param __attribute__((unused)),
3787
ulong length= net_field_length(row);
3789
if (field->max_length < length)
3790
field->max_length= length;
3795
Check that two field types are binary compatible i. e.
3796
have equal representation in the binary protocol and
3797
require client-side buffers of the same type.
3800
is_binary_compatible()
3801
type1 parameter type supplied by user
3802
type2 field type, obtained from result set metadata
3808
static my_bool is_binary_compatible(enum enum_field_types type1,
3809
enum enum_field_types type2)
3811
static const enum enum_field_types
3812
range1[]= { MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR, MYSQL_TYPE_NULL },
3813
range2[]= { MYSQL_TYPE_INT24, MYSQL_TYPE_LONG, MYSQL_TYPE_NULL },
3814
range3[]= { MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_NULL },
3815
range4[]= { MYSQL_TYPE_ENUM, MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB,
3816
MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
3817
MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY,
3818
MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NULL };
3819
static const enum enum_field_types
3820
*range_list[]= { range1, range2, range3, range4 },
3821
**range_list_end= range_list + sizeof(range_list)/sizeof(*range_list);
3822
const enum enum_field_types **range, *type;
3826
for (range= range_list; range != range_list_end; ++range)
3828
/* check that both type1 and type2 are in the same range */
3829
my_bool type1_found= FALSE, type2_found= FALSE;
3830
for (type= *range; *type != MYSQL_TYPE_NULL; type++)
3832
type1_found|= type1 == *type;
3833
type2_found|= type2 == *type;
3835
if (type1_found || type2_found)
3836
return type1_found && type2_found;
3843
Setup a fetch function for one column of a result set.
3846
setup_one_fetch_function()
3847
param output buffer descriptor
3848
field column descriptor
3851
When user binds result set buffers or when result set
3852
metadata is changed, we need to setup fetch (and possibly
3853
conversion) functions for all columns of the result set.
3854
In addition to that here we set up skip_result function, used
3855
to update result set metadata in case when
3856
STMT_ATTR_UPDATE_MAX_LENGTH attribute is set.
3857
Notice that while fetch_result is chosen depending on both
3858
field->type and param->type, skip_result depends on field->type
3862
TRUE fetch function for this typecode was not found (typecode
3863
is not supported by the client library)
3867
static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
3869
DBUG_ENTER("setup_one_fetch_function");
3871
/* Setup data copy functions for the different supported types */
3872
switch (param->buffer_type) {
3873
case MYSQL_TYPE_NULL: /* for dummy binds */
3875
It's not binary compatible with anything the server can return:
3876
no need to setup fetch_result, as it'll be reset anyway
3880
case MYSQL_TYPE_TINY:
3881
param->fetch_result= fetch_result_tinyint;
3884
case MYSQL_TYPE_SHORT:
3885
case MYSQL_TYPE_YEAR:
3886
param->fetch_result= fetch_result_short;
3889
case MYSQL_TYPE_INT24:
3890
case MYSQL_TYPE_LONG:
3891
param->fetch_result= fetch_result_int32;
3894
case MYSQL_TYPE_LONGLONG:
3895
param->fetch_result= fetch_result_int64;
3898
case MYSQL_TYPE_FLOAT:
3899
param->fetch_result= fetch_result_float;
3902
case MYSQL_TYPE_DOUBLE:
3903
param->fetch_result= fetch_result_double;
3906
case MYSQL_TYPE_TIME:
3907
param->fetch_result= fetch_result_time;
3908
*param->length= sizeof(MYSQL_TIME);
3910
case MYSQL_TYPE_DATE:
3911
param->fetch_result= fetch_result_date;
3912
*param->length= sizeof(MYSQL_TIME);
3914
case MYSQL_TYPE_DATETIME:
3915
case MYSQL_TYPE_TIMESTAMP:
3916
param->fetch_result= fetch_result_datetime;
3917
*param->length= sizeof(MYSQL_TIME);
3919
case MYSQL_TYPE_TINY_BLOB:
3920
case MYSQL_TYPE_MEDIUM_BLOB:
3921
case MYSQL_TYPE_LONG_BLOB:
3922
case MYSQL_TYPE_BLOB:
3923
case MYSQL_TYPE_BIT:
3924
DBUG_ASSERT(param->buffer_length != 0);
3925
param->fetch_result= fetch_result_bin;
3927
case MYSQL_TYPE_VAR_STRING:
3928
case MYSQL_TYPE_STRING:
3929
case MYSQL_TYPE_DECIMAL:
3930
case MYSQL_TYPE_NEWDECIMAL:
3931
case MYSQL_TYPE_NEWDATE:
3932
DBUG_ASSERT(param->buffer_length != 0);
3933
param->fetch_result= fetch_result_str;
3936
DBUG_PRINT("error", ("Unknown param->buffer_type: %u",
3937
(uint) param->buffer_type));
3940
if (! is_binary_compatible(param->buffer_type, field->type))
3941
param->fetch_result= fetch_result_with_conversion;
3943
/* Setup skip_result functions (to calculate max_length) */
3944
param->skip_result= skip_result_fixed;
3945
switch (field->type) {
3946
case MYSQL_TYPE_NULL: /* for dummy binds */
3947
param->pack_length= 0;
3948
field->max_length= 0;
3950
case MYSQL_TYPE_TINY:
3951
param->pack_length= 1;
3952
field->max_length= 4; /* as in '-127' */
3954
case MYSQL_TYPE_YEAR:
3955
case MYSQL_TYPE_SHORT:
3956
param->pack_length= 2;
3957
field->max_length= 6; /* as in '-32767' */
3959
case MYSQL_TYPE_INT24:
3960
field->max_length= 9; /* as in '16777216' or in '-8388607' */
3961
param->pack_length= 4;
3963
case MYSQL_TYPE_LONG:
3964
field->max_length= 11; /* '-2147483647' */
3965
param->pack_length= 4;
3967
case MYSQL_TYPE_LONGLONG:
3968
field->max_length= 21; /* '18446744073709551616' */
3969
param->pack_length= 8;
3971
case MYSQL_TYPE_FLOAT:
3972
param->pack_length= 4;
3973
field->max_length= MAX_DOUBLE_STRING_REP_LENGTH;
3975
case MYSQL_TYPE_DOUBLE:
3976
param->pack_length= 8;
3977
field->max_length= MAX_DOUBLE_STRING_REP_LENGTH;
3979
case MYSQL_TYPE_TIME:
3980
field->max_length= 15; /* 19:23:48.123456 */
3981
param->skip_result= skip_result_with_length;
3982
case MYSQL_TYPE_DATE:
3983
field->max_length= 10; /* 2003-11-11 */
3984
param->skip_result= skip_result_with_length;
3987
case MYSQL_TYPE_DATETIME:
3988
case MYSQL_TYPE_TIMESTAMP:
3989
param->skip_result= skip_result_with_length;
3990
field->max_length= MAX_DATE_STRING_REP_LENGTH;
3992
case MYSQL_TYPE_DECIMAL:
3993
case MYSQL_TYPE_NEWDECIMAL:
3994
case MYSQL_TYPE_ENUM:
3995
case MYSQL_TYPE_SET:
3996
case MYSQL_TYPE_GEOMETRY:
3997
case MYSQL_TYPE_TINY_BLOB:
3998
case MYSQL_TYPE_MEDIUM_BLOB:
3999
case MYSQL_TYPE_LONG_BLOB:
4000
case MYSQL_TYPE_BLOB:
4001
case MYSQL_TYPE_VAR_STRING:
4002
case MYSQL_TYPE_STRING:
4003
case MYSQL_TYPE_BIT:
4004
case MYSQL_TYPE_NEWDATE:
4005
param->skip_result= skip_result_string;
4008
DBUG_PRINT("error", ("Unknown field->type: %u", (uint) field->type));
4016
Setup the bind buffers for resultset processing
4019
my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *my_bind)
4021
MYSQL_BIND *param, *end;
4023
ulong bind_count= stmt->field_count;
4024
uint param_count= 0;
4025
DBUG_ENTER("mysql_stmt_bind_result");
4026
DBUG_PRINT("enter",("field_count: %lu", bind_count));
4030
int errorcode= (int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE ?
4031
CR_NO_PREPARE_STMT : CR_NO_STMT_METADATA;
4032
set_stmt_error(stmt, errorcode, unknown_sqlstate, NULL);
4037
We only need to check that stmt->field_count - if it is not null
4038
stmt->bind was initialized in mysql_stmt_prepare
4039
stmt->bind overlaps with bind if mysql_stmt_bind_param
4040
is called from mysql_stmt_store_result.
4043
if (stmt->bind != my_bind)
4044
memcpy((char*) stmt->bind, (char*) my_bind,
4045
sizeof(MYSQL_BIND) * bind_count);
4047
for (param= stmt->bind, end= param + bind_count, field= stmt->fields ;
4051
DBUG_PRINT("info",("buffer_type: %u field_type: %u",
4052
(uint) param->buffer_type, (uint) field->type));
4054
Set param->is_null to point to a dummy variable if it's not set.
4055
This is to make the execute code easier
4057
if (!param->is_null)
4058
param->is_null= ¶m->is_null_value;
4061
param->length= ¶m->length_value;
4064
param->error= ¶m->error_value;
4066
param->param_number= param_count++;
4069
if (setup_one_fetch_function(param, field))
4071
strmov(stmt->sqlstate, unknown_sqlstate);
4072
sprintf(stmt->last_error,
4073
ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
4074
field->type, param_count);
4078
stmt->bind_result_done= BIND_RESULT_DONE;
4079
if (stmt->mysql->options.report_data_truncation)
4080
stmt->bind_result_done|= REPORT_DATA_TRUNCATION;
4087
Fetch row data to bind buffers
4090
static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row)
4092
MYSQL_BIND *my_bind, *end;
4094
uchar *null_ptr, bit;
4095
int truncation_count= 0;
4097
Precondition: if stmt->field_count is zero or row is NULL, read_row_*
4098
function must return no data.
4100
DBUG_ASSERT(stmt->field_count);
4103
if (!stmt->bind_result_done)
4105
/* If output parameters were not bound we should just return success */
4110
row+= (stmt->field_count+9)/8; /* skip null bits */
4111
bit= 4; /* first 2 bits are reserved */
4113
/* Copy complete row to application buffers */
4114
for (my_bind= stmt->bind, end= my_bind + stmt->field_count,
4115
field= stmt->fields ;
4120
if (*null_ptr & bit)
4123
We should set both row_ptr and is_null to be able to see
4124
nulls in mysql_stmt_fetch_column. This is because is_null may point
4125
to user data which can be overwritten between mysql_stmt_fetch and
4126
mysql_stmt_fetch_column, and in this case nullness of column will be
4127
lost. See mysql_stmt_fetch_column for details.
4129
my_bind->row_ptr= NULL;
4130
*my_bind->is_null= 1;
4134
*my_bind->is_null= 0;
4135
my_bind->row_ptr= row;
4136
(*my_bind->fetch_result)(my_bind, field, &row);
4137
truncation_count+= *my_bind->error;
4139
if (!((bit<<=1) & 255))
4141
bit= 1; /* To next uchar */
4145
if (truncation_count && (stmt->bind_result_done & REPORT_DATA_TRUNCATION))
4146
return MYSQL_DATA_TRUNCATED;
4151
int cli_unbuffered_fetch(MYSQL *mysql, char **row)
4153
if (packet_error == cli_safe_read(mysql))
4156
*row= ((mysql->net.read_pos[0] == 254) ? NULL :
4157
(char*) (mysql->net.read_pos+1));
4163
Fetch and return row data to bound buffers, if any
4166
int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
4170
DBUG_ENTER("mysql_stmt_fetch");
4172
if ((rc= (*stmt->read_row_func)(stmt, &row)) ||
4173
((rc= stmt_fetch_row(stmt, row)) && rc != MYSQL_DATA_TRUNCATED))
4175
stmt->state= MYSQL_STMT_PREPARE_DONE; /* XXX: this is buggy */
4176
stmt->read_row_func= (rc == MYSQL_NO_DATA) ?
4177
stmt_read_row_no_data : stmt_read_row_no_result_set;
4181
/* This is to know in mysql_stmt_fetch_column that data was fetched */
4182
stmt->state= MYSQL_STMT_FETCH_DONE;
4189
Fetch data for one specified column data
4192
mysql_stmt_fetch_column()
4193
stmt Prepared statement handler
4194
my_bind Where data should be placed. Should be filled in as
4195
when calling mysql_stmt_bind_result()
4196
column Column to fetch (first column is 0)
4197
ulong offset Offset in result data (to fetch blob in pieces)
4204
int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *my_bind,
4205
uint column, ulong offset)
4207
MYSQL_BIND *param= stmt->bind+column;
4208
DBUG_ENTER("mysql_stmt_fetch_column");
4210
if ((int) stmt->state < (int) MYSQL_STMT_FETCH_DONE)
4212
set_stmt_error(stmt, CR_NO_DATA, unknown_sqlstate, NULL);
4215
if (column >= stmt->field_count)
4217
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate, NULL);
4221
if (!my_bind->error)
4222
my_bind->error= &my_bind->error_value;
4226
MYSQL_FIELD *field= stmt->fields+column;
4227
uchar *row= param->row_ptr;
4228
my_bind->offset= offset;
4229
if (my_bind->is_null)
4230
*my_bind->is_null= 0;
4231
if (my_bind->length) /* Set the length if non char/binary types */
4232
*my_bind->length= *param->length;
4234
my_bind->length= ¶m->length_value; /* Needed for fetch_result() */
4235
fetch_result_with_conversion(my_bind, field, &row);
4239
if (my_bind->is_null)
4240
*my_bind->is_null= 1;
4247
Read all rows of data from server (binary format)
4250
int cli_read_binary_rows(MYSQL_STMT *stmt)
4254
MYSQL *mysql= stmt->mysql;
4255
MYSQL_DATA *result= &stmt->result;
4256
MYSQL_ROWS *cur, **prev_ptr= &result->data;
4259
DBUG_ENTER("cli_read_binary_rows");
4263
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
4269
while ((pkt_len= cli_safe_read(mysql)) != packet_error)
4272
if (cp[0] != 254 || pkt_len >= 8)
4274
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
4275
sizeof(MYSQL_ROWS) + pkt_len - 1)))
4277
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
4280
cur->data= (MYSQL_ROW) (cur+1);
4282
prev_ptr= &cur->next;
4283
memcpy((char *) cur->data, (char *) cp+1, pkt_len-1);
4284
cur->length= pkt_len; /* To allow us to do sanity checks */
4291
mysql->warning_count= uint2korr(cp+1);
4292
mysql->server_status= uint2korr(cp+3);
4293
DBUG_PRINT("info",("status: %u warning_count: %u",
4294
mysql->server_status, mysql->warning_count));
4298
set_stmt_errmsg(stmt, net);
4306
Update meta data for statement
4309
stmt_update_metadata()
4310
stmt Statement handler
4314
Only updates MYSQL_FIELD->max_length for strings
4317
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data)
4319
MYSQL_BIND *my_bind, *end;
4321
uchar *null_ptr, bit;
4322
uchar *row= (uchar*) data->data;
4324
uchar *row_end= row + data->length;
4328
row+= (stmt->field_count+9)/8; /* skip null bits */
4329
bit= 4; /* first 2 bits are reserved */
4331
/* Go through all fields and calculate metadata */
4332
for (my_bind= stmt->bind, end= my_bind + stmt->field_count, field= stmt->fields ;
4336
if (!(*null_ptr & bit))
4337
(*my_bind->skip_result)(my_bind, field, &row);
4338
DBUG_ASSERT(row <= row_end);
4339
if (!((bit<<=1) & 255))
4341
bit= 1; /* To next uchar */
4349
Store or buffer the binary results to stmt
4352
int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
4354
MYSQL *mysql= stmt->mysql;
4355
MYSQL_DATA *result= &stmt->result;
4356
DBUG_ENTER("mysql_stmt_store_result");
4360
/* mysql can be reset in mysql_close called from mysql_reconnect */
4361
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
4365
if (!stmt->field_count)
4368
if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE)
4370
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
4374
if (mysql->status == MYSQL_STATUS_READY &&
4375
stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
4378
Server side cursor exist, tell server to start sending the rows
4380
NET *net= &mysql->net;
4381
uchar buff[4 /* statement id */ +
4382
4 /* number of rows to fetch */];
4384
/* Send row request to the server */
4385
int4store(buff, stmt->stmt_id);
4386
int4store(buff + 4, (int)~0); /* number of rows to fetch */
4387
if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
4388
(uchar*) 0, 0, 1, stmt))
4390
set_stmt_errmsg(stmt, net);
4394
else if (mysql->status != MYSQL_STATUS_GET_RESULT)
4396
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
4400
if (stmt->update_max_length && !stmt->bind_result_done)
4403
We must initalize the bind structure to be able to calculate
4406
MYSQL_BIND *my_bind, *end;
4408
bzero((char*) stmt->bind, sizeof(*stmt->bind)* stmt->field_count);
4410
for (my_bind= stmt->bind, end= my_bind + stmt->field_count,
4411
field= stmt->fields;
4415
my_bind->buffer_type= MYSQL_TYPE_NULL;
4416
my_bind->buffer_length=1;
4419
if (mysql_stmt_bind_result(stmt, stmt->bind))
4421
stmt->bind_result_done= 0; /* No normal bind done */
4424
if ((*mysql->methods->read_binary_rows)(stmt))
4426
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
4429
mysql->status= MYSQL_STATUS_READY;
4433
/* Assert that if there was a cursor, all rows have been fetched */
4434
DBUG_ASSERT(mysql->status != MYSQL_STATUS_READY ||
4435
(mysql->server_status & SERVER_STATUS_LAST_ROW_SENT));
4437
if (stmt->update_max_length)
4439
MYSQL_ROWS *cur= result->data;
4440
for(; cur; cur=cur->next)
4441
stmt_update_metadata(stmt, cur);
4444
stmt->data_cursor= result->data;
4445
mysql->affected_rows= stmt->affected_rows= result->rows;
4446
stmt->read_row_func= stmt_read_row_buffered;
4447
mysql->unbuffered_fetch_owner= 0; /* set in stmt_execute */
4448
mysql->status= MYSQL_STATUS_READY; /* server is ready */
4449
DBUG_RETURN(0); /* Data buffered, must be fetched with mysql_stmt_fetch() */
4454
Seek to desired row in the statement result set
4457
MYSQL_ROW_OFFSET STDCALL
4458
mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET row)
4460
MYSQL_ROW_OFFSET offset= stmt->data_cursor;
4461
DBUG_ENTER("mysql_stmt_row_seek");
4463
stmt->data_cursor= row;
4464
DBUG_RETURN(offset);
4469
Return the current statement row cursor position
4472
MYSQL_ROW_OFFSET STDCALL
4473
mysql_stmt_row_tell(MYSQL_STMT *stmt)
4475
DBUG_ENTER("mysql_stmt_row_tell");
4477
DBUG_RETURN(stmt->data_cursor);
4482
Move the stmt result set data cursor to specified row
4486
mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong row)
4488
MYSQL_ROWS *tmp= stmt->result.data;
4489
DBUG_ENTER("mysql_stmt_data_seek");
4490
DBUG_PRINT("enter",("row id to seek: %ld",(long) row));
4492
for (; tmp && row; --row, tmp= tmp->next)
4494
stmt->data_cursor= tmp;
4497
/* Rewind the counter */
4498
stmt->read_row_func= stmt_read_row_buffered;
4499
stmt->state= MYSQL_STMT_EXECUTE_DONE;
4506
Return total rows the current statement result set
4509
my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt)
4511
DBUG_ENTER("mysql_stmt_num_rows");
4513
DBUG_RETURN(stmt->result.rows);
4518
Free the client side memory buffers, reset long data state
4519
on client if necessary, and reset the server side statement if
4520
this has been requested.
4523
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
4525
/* If statement hasn't been prepared there is nothing to reset */
4526
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
4528
MYSQL *mysql= stmt->mysql;
4529
MYSQL_DATA *result= &stmt->result;
4532
Reset stored result set if so was requested or it's a part
4535
if (flags & RESET_STORE_RESULT)
4537
/* Result buffered */
4538
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
4541
stmt->data_cursor= NULL;
4543
if (flags & RESET_LONG_DATA)
4545
MYSQL_BIND *param= stmt->params, *param_end= param + stmt->param_count;
4546
/* Clear long_data_used flags */
4547
for (; param < param_end; param++)
4548
param->long_data_used= 0;
4550
stmt->read_row_func= stmt_read_row_no_result_set;
4553
if ((int) stmt->state > (int) MYSQL_STMT_PREPARE_DONE)
4555
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
4556
mysql->unbuffered_fetch_owner= 0;
4557
if (stmt->field_count && mysql->status != MYSQL_STATUS_READY)
4559
/* There is a result set and it belongs to this statement */
4560
(*mysql->methods->flush_use_result)(mysql);
4561
if (mysql->unbuffered_fetch_owner)
4562
*mysql->unbuffered_fetch_owner= TRUE;
4563
mysql->status= MYSQL_STATUS_READY;
4566
if (flags & RESET_SERVER_SIDE)
4569
Reset the server side statement and close the server side
4570
cursor if it exists.
4572
uchar buff[MYSQL_STMT_HEADER]; /* packet header: 4 bytes for stmt id */
4573
int4store(buff, stmt->stmt_id);
4574
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_RESET, buff,
4575
sizeof(buff), 0, 0, 0, stmt))
4577
set_stmt_errmsg(stmt, &mysql->net);
4578
stmt->state= MYSQL_STMT_INIT_DONE;
4581
stmt_clear_error(stmt);
4584
stmt->state= MYSQL_STMT_PREPARE_DONE;
4589
my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
4591
DBUG_ENTER("mysql_stmt_free_result");
4593
/* Free the client side and close the server side cursor if there is one */
4594
DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT));
4597
/********************************************************************
4598
statement error handling and close
4599
*********************************************************************/
4602
Close the statement handle by freeing all alloced resources
4606
stmt Statement handle
4613
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
4615
MYSQL *mysql= stmt->mysql;
4617
DBUG_ENTER("mysql_stmt_close");
4619
free_root(&stmt->result.alloc, MYF(0));
4620
free_root(&stmt->mem_root, MYF(0));
4624
mysql->stmts= list_delete(mysql->stmts, &stmt->list);
4626
Clear NET error state: if the following commands come through
4627
successfully, connection will still be usable for other commands.
4629
net_clear_error(&mysql->net);
4630
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
4632
uchar buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
4634
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
4635
mysql->unbuffered_fetch_owner= 0;
4636
if (mysql->status != MYSQL_STATUS_READY)
4639
Flush result set of the connection. If it does not belong
4640
to this statement, set a warning.
4642
(*mysql->methods->flush_use_result)(mysql);
4643
if (mysql->unbuffered_fetch_owner)
4644
*mysql->unbuffered_fetch_owner= TRUE;
4645
mysql->status= MYSQL_STATUS_READY;
4647
int4store(buff, stmt->stmt_id);
4648
if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
4650
set_stmt_errmsg(stmt, &mysql->net);
4655
my_free((uchar*) stmt, MYF(MY_WME));
4657
DBUG_RETURN(test(rc));
4661
Reset the statement buffers in server
4664
my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
4666
DBUG_ENTER("mysql_stmt_reset");
4667
DBUG_ASSERT(stmt != 0);
4670
/* mysql can be reset in mysql_close called from mysql_reconnect */
4671
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
4674
/* Reset the client and server sides of the prepared statement */
4675
DBUG_RETURN(reset_stmt_handle(stmt, RESET_SERVER_SIDE | RESET_LONG_DATA));
4679
Return statement error code
4682
uint STDCALL mysql_stmt_errno(MYSQL_STMT * stmt)
4684
DBUG_ENTER("mysql_stmt_errno");
4685
DBUG_RETURN(stmt->last_errno);
4688
const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt)
4690
DBUG_ENTER("mysql_stmt_sqlstate");
4691
DBUG_RETURN(stmt->sqlstate);
4695
Return statement error message
4698
const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt)
4700
DBUG_ENTER("mysql_stmt_error");
4701
DBUG_RETURN(stmt->last_error);
4705
/********************************************************************
4707
*********************************************************************/
4710
Commit the current transaction
4713
my_bool STDCALL mysql_commit(MYSQL * mysql)
4715
DBUG_ENTER("mysql_commit");
4716
DBUG_RETURN((my_bool) mysql_real_query(mysql, "commit", 6));
4720
Rollback the current transaction
4723
my_bool STDCALL mysql_rollback(MYSQL * mysql)
4725
DBUG_ENTER("mysql_rollback");
4726
DBUG_RETURN((my_bool) mysql_real_query(mysql, "rollback", 8));
4731
Set autocommit to either true or false
4734
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode)
4736
DBUG_ENTER("mysql_autocommit");
4737
DBUG_PRINT("enter", ("mode : %d", auto_mode));
4739
DBUG_RETURN((my_bool) mysql_real_query(mysql, auto_mode ?
4740
"set autocommit=1":"set autocommit=0",
4745
/********************************************************************
4746
Multi query execution + SPs APIs
4747
*********************************************************************/
4750
Returns true/false to indicate whether any more query results exist
4751
to be read using mysql_next_result()
4754
my_bool STDCALL mysql_more_results(MYSQL *mysql)
4757
DBUG_ENTER("mysql_more_results");
4759
res= ((mysql->server_status & SERVER_MORE_RESULTS_EXISTS) ? 1: 0);
4760
DBUG_PRINT("exit",("More results exists ? %d", res));
4766
Reads and returns the next query results
4768
int STDCALL mysql_next_result(MYSQL *mysql)
4770
DBUG_ENTER("mysql_next_result");
4772
if (mysql->status != MYSQL_STATUS_READY)
4774
set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
4778
net_clear_error(&mysql->net);
4779
mysql->affected_rows= ~(my_ulonglong) 0;
4781
if (mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
4782
DBUG_RETURN((*mysql->methods->next_result)(mysql));
4784
DBUG_RETURN(-1); /* No more results */
4788
MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql)
4790
return (*mysql->methods->use_result)(mysql);
4793
my_bool STDCALL mysql_read_query_result(MYSQL *mysql)
4795
return (*mysql->methods->read_query_result)(mysql);