1265
1281
'emb_' reside in libmysqld/lib_sql.cc.
1266
1282
*********************************************************************/
1284
/******************* Declarations ***********************************/
1286
/* Default number of rows fetched per one COM_STMT_FETCH command. */
1288
#define DEFAULT_PREFETCH_ROWS (ulong) 1
1291
These functions are called by function pointer MYSQL_STMT::read_row_func.
1292
Each function corresponds to one of the read methods:
1293
- mysql_stmt_fetch without prior mysql_stmt_store_result,
1294
- mysql_stmt_fetch when result is stored,
1295
- mysql_stmt_fetch when there are no rows (always returns MYSQL_NO_DATA)
1298
static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row);
1299
static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row);
1300
static int stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row);
1301
static int stmt_read_row_no_data(MYSQL_STMT *stmt, unsigned char **row);
1302
static int stmt_read_row_no_result_set(MYSQL_STMT *stmt, unsigned char **row);
1305
This function is used in mysql_stmt_store_result if
1306
STMT_ATTR_UPDATE_MAX_LENGTH attribute is set.
1308
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data);
1309
static my_bool setup_one_fetch_function(MYSQL_BIND *, MYSQL_FIELD *field);
1311
/* Auxilary function used to reset statement handle. */
1313
#define RESET_SERVER_SIDE 1
1314
#define RESET_LONG_DATA 2
1315
#define RESET_STORE_RESULT 4
1317
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags);
1320
Maximum sizes of MYSQL_TYPE_DATE, MYSQL_TYPE_TIME, MYSQL_TYPE_DATETIME
1321
values stored in network buffer.
1324
/* 1 (length) + 2 (year) + 1 (month) + 1 (day) */
1325
#define MAX_DATE_REP_LENGTH 5
1328
1 (length) + 1 (is negative) + 4 (day count) + 1 (hour)
1329
+ 1 (minute) + 1 (seconds) + 4 (microseconds)
1331
#define MAX_TIME_REP_LENGTH 13
1334
1 (length) + 2 (year) + 1 (month) + 1 (day) +
1335
1 (hour) + 1 (minute) + 1 (second) + 4 (microseconds)
1337
#define MAX_DATETIME_REP_LENGTH 12
1339
#define MAX_DOUBLE_STRING_REP_LENGTH 331
1341
/* A macro to check truncation errors */
1343
#define IS_TRUNCATED(value, is_unsigned, min, max, umax) \
1344
((is_unsigned) ? (((value) > (umax) || (value) < 0) ? 1 : 0) : \
1345
(((value) > (max) || (value) < (min)) ? 1 : 0))
1347
#define BIND_RESULT_DONE 1
1349
We report truncations only if at least one of MYSQL_BIND::error
1350
pointers is set. In this case stmt->bind_result_done |-ed with
1353
#define REPORT_DATA_TRUNCATION 2
1355
/**************** Misc utility functions ****************************/
1358
Reallocate the NET package to have at least length bytes available.
1362
net The NET structure to modify.
1363
length Ensure that net->buff has space for at least
1364
this number of bytes.
1368
1 Error, i.e. out of memory or requested packet size is bigger
1369
than max_allowed_packet. The error code is stored in net->last_errno.
1372
static my_bool my_realloc_str(NET *net, ulong length)
1374
ulong buf_length= (ulong) (net->write_pos - net->buff);
1376
DBUG_ENTER("my_realloc_str");
1377
if (buf_length + length > net->max_packet)
1379
res= net_realloc(net, buf_length + length);
1382
strmov(net->sqlstate, unknown_sqlstate);
1383
strmov(net->last_error, ER(net->last_errno));
1385
net->write_pos= net->buff+ buf_length;
1391
static void stmt_clear_error(MYSQL_STMT *stmt)
1393
if (stmt->last_errno)
1395
stmt->last_errno= 0;
1396
stmt->last_error[0]= '\0';
1397
strmov(stmt->sqlstate, not_error_sqlstate);
1402
Set statement error code, sqlstate, and error message
1403
from given errcode and sqlstate.
1406
void set_stmt_error(MYSQL_STMT * stmt, int errcode,
1407
const char *sqlstate, const char *err)
1409
DBUG_ENTER("set_stmt_error");
1410
DBUG_PRINT("enter", ("error: %d '%s'", errcode, ER(errcode)));
1411
DBUG_ASSERT(stmt != 0);
1416
stmt->last_errno= errcode;
1417
strmov(stmt->last_error, ER(errcode));
1418
strmov(stmt->sqlstate, sqlstate);
1425
Set statement error code, sqlstate, and error message from NET.
1427
@param stmt a statement handle. Copy the error here.
1428
@param net mysql->net. Source of the error.
1431
void set_stmt_errmsg(MYSQL_STMT *stmt, NET *net)
1433
DBUG_ENTER("set_stmt_errmsg");
1434
DBUG_PRINT("enter", ("error: %d/%s '%s'",
1438
DBUG_ASSERT(stmt != 0);
1440
stmt->last_errno= net->last_errno;
1441
if (net->last_error && net->last_error[0])
1442
strmov(stmt->last_error, net->last_error);
1443
strmov(stmt->sqlstate, net->sqlstate);
1449
Read and unpack server reply to COM_STMT_PREPARE command (sent from
1450
mysql_stmt_prepare).
1453
cli_read_prepare_result()
1454
mysql connection handle
1455
stmt statement handle
1462
my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
1465
uint field_count, param_count;
1466
ulong packet_length;
1467
MYSQL_DATA *fields_data;
1468
DBUG_ENTER("cli_read_prepare_result");
1470
if ((packet_length= cli_safe_read(mysql)) == packet_error)
1472
mysql->warning_count= 0;
1474
pos= (uchar*) mysql->net.read_pos;
1475
stmt->stmt_id= uint4korr(pos+1); pos+= 5;
1476
/* Number of columns in result set */
1477
field_count= uint2korr(pos); pos+= 2;
1478
/* Number of placeholders in the statement */
1479
param_count= uint2korr(pos); pos+= 2;
1480
if (packet_length >= 12)
1481
mysql->warning_count= uint2korr(pos+1);
1483
if (param_count != 0)
1485
MYSQL_DATA *param_data;
1487
/* skip parameters data: we don't support it yet */
1488
if (!(param_data= (*mysql->methods->read_rows)(mysql, (MYSQL_FIELD*)0, 7)))
1490
free_rows(param_data);
1493
if (field_count != 0)
1495
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
1496
mysql->server_status|= SERVER_STATUS_IN_TRANS;
1498
if (!(fields_data= (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,7)))
1500
if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root,
1502
mysql->server_capabilities)))
1505
stmt->field_count= field_count;
1506
stmt->param_count= (ulong) param_count;
1507
DBUG_PRINT("exit",("field_count: %u param_count: %u warning_count: %u",
1508
field_count, param_count, (uint) mysql->warning_count));
1515
Allocate memory and init prepared statement structure.
1519
mysql connection handle
1522
This is an entry point of the new API. Returned handle stands for
1523
a server-side prepared statement. Memory for this structure (~700
1524
bytes) is allocated using 'malloc'. Once created, the handle can be
1525
reused many times. Created statement handle is bound to connection
1526
handle provided to this call: its lifetime is limited by lifetime
1528
'mysql_stmt_init()' is a pure local call, server side structure is
1529
created only in mysql_stmt_prepare.
1530
Next steps you may want to make:
1531
- set a statement attribute (mysql_stmt_attr_set()),
1532
- prepare statement handle with a query (mysql_stmt_prepare()),
1533
- close statement handle and free its memory (mysql_stmt_close()),
1534
- reset statement with mysql_stmt_reset() (a no-op which will
1536
Behaviour of the rest of API calls on this statement is not defined yet
1537
(though we're working on making each wrong call sequence return
1541
statement structure upon success and NULL if out of
1545
MYSQL_STMT * STDCALL
1546
mysql_stmt_init(MYSQL *mysql)
1549
DBUG_ENTER("mysql_stmt_init");
1551
if (!(stmt= (MYSQL_STMT *) my_malloc(sizeof(MYSQL_STMT),
1552
MYF(MY_WME | MY_ZEROFILL))))
1554
set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate);
1558
init_alloc_root(&stmt->mem_root, 2048, 2048);
1559
init_alloc_root(&stmt->result.alloc, 4096, 4096);
1560
stmt->result.alloc.min_malloc= sizeof(MYSQL_ROWS);
1561
mysql->stmts= list_add(mysql->stmts, &stmt->list);
1562
stmt->list.data= stmt;
1563
stmt->state= MYSQL_STMT_INIT_DONE;
1565
stmt->read_row_func= stmt_read_row_no_result_set;
1566
stmt->prefetch_rows= DEFAULT_PREFETCH_ROWS;
1567
strmov(stmt->sqlstate, not_error_sqlstate);
1568
/* The rest of statement members was bzeroed inside malloc */
1575
Prepare server side statement with query.
1578
mysql_stmt_prepare()
1579
stmt statement handle
1580
query statement to prepare
1581
length statement length
1584
Associate statement with statement handle. This is done both on
1585
client and server sides. At this point the server parses given query
1586
and creates an internal structure to represent it.
1587
Next steps you may want to make:
1588
- find out if this statement returns a result set by
1589
calling mysql_stmt_field_count(), and get result set metadata
1590
with mysql_stmt_result_metadata(),
1591
- if query contains placeholders, bind input parameters to placeholders
1592
using mysql_stmt_bind_param(),
1593
- otherwise proceed directly to mysql_stmt_execute().
1595
IMPLEMENTATION NOTES
1596
- if this is a re-prepare of the statement, first close previous data
1597
structure on the server and free old statement data
1598
- then send the query to server and get back number of placeholders,
1599
number of columns in result set (if any), and result set metadata.
1600
At the same time allocate memory for input and output parameters
1601
to have less checks in mysql_stmt_bind_{param, result}.
1609
mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
1611
MYSQL *mysql= stmt->mysql;
1612
DBUG_ENTER("mysql_stmt_prepare");
1616
/* mysql can be reset in mysql_close called from mysql_reconnect */
1617
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
1622
Reset the last error in any case: that would clear the statement
1623
if the previous prepare failed.
1625
stmt->last_errno= 0;
1626
stmt->last_error[0]= '\0';
1628
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
1630
/* This is second prepare with another statement */
1631
uchar buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
1633
if (reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT))
1636
These members must be reset for API to
1637
function in case of error or misuse.
1639
stmt->bind_param_done= stmt->bind_result_done= FALSE;
1640
stmt->param_count= stmt->field_count= 0;
1641
free_root(&stmt->mem_root, MYF(MY_KEEP_PREALLOC));
1643
int4store(buff, stmt->stmt_id);
1646
Close statement in server
1648
If there was a 'use' result from another statement, or from
1649
mysql_use_result it won't be freed in mysql_stmt_free_result and
1650
we should get 'Commands out of sync' here.
1652
stmt->state= MYSQL_STMT_INIT_DONE;
1653
if (stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt))
1655
set_stmt_errmsg(stmt, &mysql->net);
1660
if (stmt_command(mysql, COM_STMT_PREPARE, (const uchar*) query, length, stmt))
1662
set_stmt_errmsg(stmt, &mysql->net);
1666
if ((*mysql->methods->read_prepare_result)(mysql, stmt))
1668
set_stmt_errmsg(stmt, &mysql->net);
1673
alloc_root will return valid address even in case when param_count
1674
and field_count are zero. Thus we should never rely on stmt->bind
1675
or stmt->params when checking for existence of placeholders or
1678
if (!(stmt->params= (MYSQL_BIND *) alloc_root(&stmt->mem_root,
1680
(stmt->param_count +
1681
stmt->field_count))))
1683
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
1686
stmt->bind= stmt->params + stmt->param_count;
1687
stmt->state= MYSQL_STMT_PREPARE_DONE;
1688
DBUG_PRINT("info", ("Parameter count: %u", stmt->param_count));
1693
Get result set metadata from reply to mysql_stmt_execute.
1694
This is used mainly for SHOW commands, as metadata for these
1695
commands is sent only with result set.
1696
To be removed when all commands will fully support prepared mode.
1699
static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
1701
MYSQL_FIELD *fields, *field, *end;
1702
MEM_ROOT *alloc= &stmt->mem_root;
1703
MYSQL *mysql= stmt->mysql;
1705
stmt->field_count= mysql->field_count;
1708
Get the field information for non-select statements
1709
like SHOW and DESCRIBE commands
1711
if (!(stmt->fields= (MYSQL_FIELD *) alloc_root(alloc,
1712
sizeof(MYSQL_FIELD) *
1713
stmt->field_count)) ||
1714
!(stmt->bind= (MYSQL_BIND *) alloc_root(alloc,
1715
sizeof(MYSQL_BIND) *
1716
stmt->field_count)))
1719
for (fields= mysql->fields, end= fields+stmt->field_count,
1720
field= stmt->fields;
1721
field && fields < end; fields++, field++)
1723
field->db = strdup_root(alloc,fields->db);
1724
field->table = strdup_root(alloc,fields->table);
1725
field->org_table= strdup_root(alloc,fields->org_table);
1726
field->name = strdup_root(alloc,fields->name);
1727
field->org_name = strdup_root(alloc,fields->org_name);
1728
field->charsetnr= fields->charsetnr;
1729
field->length = fields->length;
1730
field->type = fields->type;
1731
field->flags = fields->flags;
1732
field->decimals = fields->decimals;
1733
field->def = fields->def ? strdup_root(alloc,fields->def): 0;
1734
field->max_length= 0;
1736
return stmt->field_count;
1741
Update result set columns metadata if it was sent again in
1742
reply to COM_STMT_EXECUTE.
1745
static void update_stmt_fields(MYSQL_STMT *stmt)
1747
MYSQL_FIELD *field= stmt->mysql->fields;
1748
MYSQL_FIELD *field_end= field + stmt->field_count;
1749
MYSQL_FIELD *stmt_field= stmt->fields;
1750
MYSQL_BIND *my_bind= stmt->bind_result_done ? stmt->bind : 0;
1752
DBUG_ASSERT(stmt->field_count == stmt->mysql->field_count);
1754
for (; field < field_end; ++field, ++stmt_field)
1756
stmt_field->charsetnr= field->charsetnr;
1757
stmt_field->length = field->length;
1758
stmt_field->type = field->type;
1759
stmt_field->flags = field->flags;
1760
stmt_field->decimals = field->decimals;
1763
/* Ignore return value: it should be 0 if bind_result succeeded. */
1764
(void) setup_one_fetch_function(my_bind++, stmt_field);
1770
Returns prepared statement metadata in the form of a result set.
1773
mysql_stmt_result_metadata()
1774
stmt statement handle
1777
This function should be used after mysql_stmt_execute().
1778
You can safely check that prepared statement has a result set by calling
1779
mysql_stmt_field_count(): if number of fields is not zero, you can call
1780
this function to get fields metadata.
1781
Next steps you may want to make:
1782
- find out number of columns in result set by calling
1783
mysql_num_fields(res) (the same value is returned by
1784
mysql_stmt_field_count())
1785
- fetch metadata for any column with mysql_fetch_field,
1786
mysql_fetch_field_direct, mysql_fetch_fields, mysql_field_seek.
1787
- free returned MYSQL_RES structure with mysql_free_result.
1788
- proceed to binding of output parameters.
1791
NULL statement contains no result set or out of memory.
1792
In the latter case you can retreive error message
1793
with mysql_stmt_error.
1794
MYSQL_RES a result set with no rows
1798
mysql_stmt_result_metadata(MYSQL_STMT *stmt)
1801
DBUG_ENTER("mysql_stmt_result_metadata");
1804
stmt->fields is only defined if stmt->field_count is not null;
1805
stmt->field_count is initialized in prepare.
1807
if (!stmt->field_count)
1810
if (!(result=(MYSQL_RES*) my_malloc(sizeof(*result),
1811
MYF(MY_WME | MY_ZEROFILL))))
1813
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
1817
result->methods= stmt->mysql->methods;
1818
result->eof= 1; /* Marker for buffered */
1819
result->fields= stmt->fields;
1820
result->field_count= stmt->field_count;
1821
/* The rest of members of 'result' was bzeroed inside malloc */
1822
DBUG_RETURN(result);
1827
Returns parameter columns meta information in the form of
1831
mysql_stmt_param_metadata()
1832
stmt statement handle
1835
This function can be called after you prepared the statement handle
1836
with mysql_stmt_prepare().
1837
XXX: not implemented yet.
1840
MYSQL_RES on success, 0 if there is no metadata.
1841
Currently this function always returns 0.
1845
mysql_stmt_param_metadata(MYSQL_STMT *stmt)
1847
DBUG_ENTER("mysql_stmt_param_metadata");
1849
if (!stmt->param_count)
1853
TODO: Fix this when server sends the information.
1854
Till then keep a dummy prototype.
1860
/* Store type of parameter in network buffer. */
1862
static void store_param_type(char **pos, MYSQL_BIND *param)
1864
uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0);
1865
int2store(*pos, typecode);
1871
Functions to store parameter data in network packet.
1875
net MySQL NET connection
1876
param MySQL bind param
1879
These funtions are invoked from mysql_stmt_execute() by
1880
MYSQL_BIND::store_param_func pointer. This pointer is set once per
1881
many executions in mysql_stmt_bind_param(). The caller must ensure
1882
that network buffer have enough capacity to store parameter
1883
(MYSQL_BIND::buffer_length contains needed number of bytes).
1886
static void store_param_tinyint(NET *net, MYSQL_BIND *param)
1888
*(net->write_pos++)= *(uchar *) param->buffer;
1891
static void store_param_short(NET *net, MYSQL_BIND *param)
1893
short value= *(short*) param->buffer;
1894
int2store(net->write_pos,value);
1898
static void store_param_int32(NET *net, MYSQL_BIND *param)
1900
int32 value= *(int32*) param->buffer;
1901
int4store(net->write_pos,value);
1905
static void store_param_int64(NET *net, MYSQL_BIND *param)
1907
longlong value= *(longlong*) param->buffer;
1908
int8store(net->write_pos,value);
1912
static void store_param_float(NET *net, MYSQL_BIND *param)
1914
float value= *(float*) param->buffer;
1915
float4store(net->write_pos, value);
1919
static void store_param_double(NET *net, MYSQL_BIND *param)
1921
double value= *(double*) param->buffer;
1922
float8store(net->write_pos, value);
1926
static void store_param_time(NET *net, MYSQL_BIND *param)
1928
MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
1929
char buff[MAX_TIME_REP_LENGTH], *pos;
1933
pos[0]= tm->neg ? 1: 0;
1934
int4store(pos+1, tm->day);
1935
pos[5]= (uchar) tm->hour;
1936
pos[6]= (uchar) tm->minute;
1937
pos[7]= (uchar) tm->second;
1938
int4store(pos+8, tm->second_part);
1939
if (tm->second_part)
1941
else if (tm->hour || tm->minute || tm->second || tm->day)
1945
buff[0]= (char) length++;
1946
memcpy((char *)net->write_pos, buff, length);
1947
net->write_pos+= length;
1950
static void net_store_datetime(NET *net, MYSQL_TIME *tm)
1952
char buff[MAX_DATETIME_REP_LENGTH], *pos;
1957
int2store(pos, tm->year);
1958
pos[2]= (uchar) tm->month;
1959
pos[3]= (uchar) tm->day;
1960
pos[4]= (uchar) tm->hour;
1961
pos[5]= (uchar) tm->minute;
1962
pos[6]= (uchar) tm->second;
1963
int4store(pos+7, tm->second_part);
1964
if (tm->second_part)
1966
else if (tm->hour || tm->minute || tm->second)
1968
else if (tm->year || tm->month || tm->day)
1972
buff[0]= (char) length++;
1973
memcpy((char *)net->write_pos, buff, length);
1974
net->write_pos+= length;
1977
static void store_param_date(NET *net, MYSQL_BIND *param)
1979
MYSQL_TIME tm= *((MYSQL_TIME *) param->buffer);
1980
tm.hour= tm.minute= tm.second= tm.second_part= 0;
1981
net_store_datetime(net, &tm);
1984
static void store_param_datetime(NET *net, MYSQL_BIND *param)
1986
MYSQL_TIME *tm= (MYSQL_TIME *) param->buffer;
1987
net_store_datetime(net, tm);
1990
static void store_param_str(NET *net, MYSQL_BIND *param)
1992
/* param->length is always set in mysql_stmt_bind_param */
1993
ulong length= *param->length;
1994
uchar *to= net_store_length(net->write_pos, length);
1995
memcpy(to, param->buffer, length);
1996
net->write_pos= to+length;
2001
Mark if the parameter is NULL.
2005
net MySQL NET connection
2006
param MySQL bind param
2009
A data package starts with a string of bits where we set a bit
2010
if a parameter is NULL. Unlike bit string in result set row, here
2011
we don't have reserved bits for OK/error packet.
2014
static void store_param_null(NET *net, MYSQL_BIND *param)
2016
uint pos= param->param_number;
2017
net->buff[pos/8]|= (uchar) (1 << (pos & 7));
2022
Store one parameter in network packet: data is read from
2023
client buffer and saved in network packet by means of one
2024
of store_param_xxxx functions.
2027
static my_bool store_param(MYSQL_STMT *stmt, MYSQL_BIND *param)
2029
NET *net= &stmt->mysql->net;
2030
DBUG_ENTER("store_param");
2031
DBUG_PRINT("enter",("type: %d buffer: 0x%lx length: %lu is_null: %d",
2033
(long) (param->buffer ? param->buffer : NullS),
2034
*param->length, *param->is_null));
2036
if (*param->is_null)
2037
store_param_null(net, param);
2041
Param->length should ALWAYS point to the correct length for the type
2042
Either to the length pointer given by the user or param->buffer_length
2044
if ((my_realloc_str(net, *param->length)))
2046
set_stmt_errmsg(stmt, net);
2049
(*param->store_param_func)(net, param);
2056
Auxilary function to send COM_STMT_EXECUTE packet to server and read reply.
2057
Used from cli_stmt_execute, which is in turn used by mysql_stmt_execute.
2060
static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
2062
MYSQL *mysql= stmt->mysql;
2063
NET *net= &mysql->net;
2064
uchar buff[4 /* size of stmt id */ +
2065
5 /* execution flags */];
2067
DBUG_ENTER("execute");
2068
DBUG_DUMP("packet", (uchar *) packet, length);
2070
int4store(buff, stmt->stmt_id); /* Send stmt id to server */
2071
buff[4]= (char) stmt->flags;
2072
int4store(buff+5, 1); /* iteration count */
2074
res= test(cli_advanced_command(mysql, COM_STMT_EXECUTE, buff, sizeof(buff),
2075
(uchar*) packet, length, 1, stmt) ||
2076
(*mysql->methods->read_query_result)(mysql));
2077
stmt->affected_rows= mysql->affected_rows;
2078
stmt->server_status= mysql->server_status;
2079
stmt->insert_id= mysql->insert_id;
2082
set_stmt_errmsg(stmt, net);
2089
int cli_stmt_execute(MYSQL_STMT *stmt)
2091
DBUG_ENTER("cli_stmt_execute");
2093
if (stmt->param_count)
2095
MYSQL *mysql= stmt->mysql;
2096
NET *net= &mysql->net;
2097
MYSQL_BIND *param, *param_end;
2103
if (!stmt->bind_param_done)
2105
set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate, NULL);
2108
if (mysql->status != MYSQL_STATUS_READY ||
2109
mysql->server_status & SERVER_MORE_RESULTS_EXISTS)
2111
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
2115
net_clear(net, 1); /* Sets net->write_pos */
2116
/* Reserve place for null-marker bytes */
2117
null_count= (stmt->param_count+7) /8;
2118
if (my_realloc_str(net, null_count + 1))
2120
set_stmt_errmsg(stmt, net);
2123
bzero((char*) net->write_pos, null_count);
2124
net->write_pos+= null_count;
2125
param_end= stmt->params + stmt->param_count;
2127
/* In case if buffers (type) altered, indicate to server */
2128
*(net->write_pos)++= (uchar) stmt->send_types_to_server;
2129
if (stmt->send_types_to_server)
2131
if (my_realloc_str(net, 2 * stmt->param_count))
2133
set_stmt_errmsg(stmt, net);
2137
Store types of parameters in first in first package
2138
that is sent to the server.
2140
for (param= stmt->params; param < param_end ; param++)
2141
store_param_type((char**) &net->write_pos, param);
2144
for (param= stmt->params; param < param_end; param++)
2146
/* check if mysql_stmt_send_long_data() was used */
2147
if (param->long_data_used)
2148
param->long_data_used= 0; /* Clear for next execute call */
2149
else if (store_param(stmt, param))
2152
length= (ulong) (net->write_pos - net->buff);
2153
/* TODO: Look into avoding the following memdup */
2154
if (!(param_data= my_memdup(net->buff, length, MYF(0))))
2156
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
2159
result= execute(stmt, param_data, length);
2160
stmt->send_types_to_server=0;
2161
my_free(param_data, MYF(MY_WME));
2162
DBUG_RETURN(result);
2164
DBUG_RETURN((int) execute(stmt,0,0));
2168
Read one row from buffered result set. Result set is created by prior
2169
call to mysql_stmt_store_result().
2171
stmt_read_row_buffered()
2174
0 - success; *row is set to valid row pointer (row data
2175
is stored in result set buffer)
2176
MYSQL_NO_DATA - end of result set. *row is set to NULL
2179
static int stmt_read_row_buffered(MYSQL_STMT *stmt, unsigned char **row)
2181
if (stmt->data_cursor)
2183
*row= (uchar *) stmt->data_cursor->data;
2184
stmt->data_cursor= stmt->data_cursor->next;
2188
return MYSQL_NO_DATA;
2192
Read one row from network: unbuffered non-cursor fetch.
2193
If last row was read, or error occured, erase this statement
2194
from record pointing to object unbuffered fetch is performed from.
2197
stmt_read_row_unbuffered()
2198
stmt statement handle
2199
row pointer to write pointer to row data;
2202
0 - success; *row contains valid address of a row;
2203
row data is stored in network buffer
2204
1 - error; error code is written to
2205
stmt->last_{errno,error}; *row is not changed
2206
MYSQL_NO_DATA - end of file was read from network;
2210
static int stmt_read_row_unbuffered(MYSQL_STMT *stmt, unsigned char **row)
2213
MYSQL *mysql= stmt->mysql;
2215
This function won't be called if stmt->field_count is zero
2216
or execution wasn't done: this is ensured by mysql_stmt_execute.
2220
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
2223
if (mysql->status != MYSQL_STATUS_GET_RESULT)
2225
set_stmt_error(stmt, stmt->unbuffered_fetch_cancelled ?
2226
CR_FETCH_CANCELED : CR_COMMANDS_OUT_OF_SYNC,
2227
unknown_sqlstate, NULL);
2230
if ((*mysql->methods->unbuffered_fetch)(mysql, (char**) row))
2232
set_stmt_errmsg(stmt, &mysql->net);
2234
If there was an error, there are no more pending rows:
2235
reset statement status to not hang up in following
2236
mysql_stmt_close (it will try to flush result set before
2237
closing the statement).
2239
mysql->status= MYSQL_STATUS_READY;
2244
mysql->status= MYSQL_STATUS_READY;
2250
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
2251
mysql->unbuffered_fetch_owner= 0;
2257
Fetch statement row using server side cursor.
2260
stmt_read_row_from_cursor()
2265
MYSQL_NO_DATA end of data
2269
stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
2271
if (stmt->data_cursor)
2272
return stmt_read_row_buffered(stmt, row);
2273
if (stmt->server_status & SERVER_STATUS_LAST_ROW_SENT)
2274
stmt->server_status &= ~SERVER_STATUS_LAST_ROW_SENT;
2277
MYSQL *mysql= stmt->mysql;
2278
NET *net= &mysql->net;
2279
MYSQL_DATA *result= &stmt->result;
2280
uchar buff[4 /* statement id */ +
2281
4 /* number of rows to fetch */];
2283
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
2286
/* Send row request to the server */
2287
int4store(buff, stmt->stmt_id);
2288
int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
2289
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
2290
buff, sizeof(buff), (uchar*) 0, 0,
2293
set_stmt_errmsg(stmt, net);
2296
if ((*mysql->methods->read_rows_from_cursor)(stmt))
2298
stmt->server_status= mysql->server_status;
2300
stmt->data_cursor= result->data;
2301
return stmt_read_row_buffered(stmt, row);
2304
return MYSQL_NO_DATA;
2309
Default read row function to not SIGSEGV in client in
2310
case of wrong sequence of API calls.
2314
stmt_read_row_no_data(MYSQL_STMT *stmt __attribute__((unused)),
2315
unsigned char **row __attribute__((unused)))
2317
return MYSQL_NO_DATA;
2321
stmt_read_row_no_result_set(MYSQL_STMT *stmt __attribute__((unused)),
2322
unsigned char **row __attribute__((unused)))
2324
set_stmt_error(stmt, CR_NO_RESULT_SET, unknown_sqlstate, NULL);
2330
Get/set statement attributes
2333
mysql_stmt_attr_get()
2334
mysql_stmt_attr_set()
2336
attr_type statement attribute
2337
value casted to const void * pointer to value.
2341
!0 wrong attribute type
2344
my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt,
2345
enum enum_stmt_attr_type attr_type,
2348
switch (attr_type) {
2349
case STMT_ATTR_UPDATE_MAX_LENGTH:
2350
stmt->update_max_length= value ? *(const my_bool*) value : 0;
2352
case STMT_ATTR_CURSOR_TYPE:
2355
cursor_type= value ? *(ulong*) value : 0UL;
2356
if (cursor_type > (ulong) CURSOR_TYPE_READ_ONLY)
2357
goto err_not_implemented;
2358
stmt->flags= cursor_type;
2361
case STMT_ATTR_PREFETCH_ROWS:
2363
ulong prefetch_rows= value ? *(ulong*) value : DEFAULT_PREFETCH_ROWS;
2366
stmt->prefetch_rows= prefetch_rows;
2370
goto err_not_implemented;
2373
err_not_implemented:
2374
set_stmt_error(stmt, CR_NOT_IMPLEMENTED, unknown_sqlstate, NULL);
2379
my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
2380
enum enum_stmt_attr_type attr_type,
2383
switch (attr_type) {
2384
case STMT_ATTR_UPDATE_MAX_LENGTH:
2385
*(my_bool*) value= stmt->update_max_length;
2387
case STMT_ATTR_CURSOR_TYPE:
2388
*(ulong*) value= stmt->flags;
2390
case STMT_ATTR_PREFETCH_ROWS:
2391
*(ulong*) value= stmt->prefetch_rows;
2401
Send placeholders data to server (if there are placeholders)
2402
and execute prepared statement.
2405
mysql_stmt_execute()
2406
stmt statement handle. The handle must be created
2407
with mysql_stmt_init() and prepared with
2408
mysql_stmt_prepare(). If there are placeholders
2409
in the statement they must be bound to local
2410
variables with mysql_stmt_bind_param().
2413
This function will automatically flush pending result
2414
set (if there is one), send parameters data to the server
2415
and read result of statement execution.
2416
If previous result set was cached with mysql_stmt_store_result()
2417
it will also be freed in the beginning of this call.
2418
The server can return 3 types of responses to this command:
2419
- error, can be retrieved with mysql_stmt_error()
2420
- ok, no result set pending. In this case we just update
2421
stmt->insert_id and stmt->affected_rows.
2422
- the query returns a result set: there could be 0 .. N
2423
rows in it. In this case the server can also send updated
2424
result set metadata.
2426
Next steps you may want to make:
2427
- find out if there is result set with mysql_stmt_field_count().
2429
- optionally, cache entire result set on client to unblock
2430
connection with mysql_stmt_store_result()
2431
- bind client variables to result set columns and start read rows
2432
with mysql_stmt_fetch().
2433
- reset statement with mysql_stmt_reset() or close it with
2436
- find out last insert id and number of affected rows with
2437
mysql_stmt_insert_id(), mysql_stmt_affected_rows()
2441
1 error, message can be retrieved with mysql_stmt_error().
2444
int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
2446
MYSQL *mysql= stmt->mysql;
2447
DBUG_ENTER("mysql_stmt_execute");
2451
/* Error is already set in mysql_detatch_stmt_list */
2455
if (reset_stmt_handle(stmt, RESET_STORE_RESULT))
2458
No need to check for stmt->state: if the statement wasn't
2459
prepared we'll get 'unknown statement handler' error from server.
2461
if (mysql->methods->stmt_execute(stmt))
2463
if (mysql->field_count)
2465
/* Server has sent result set metadata */
2466
if (stmt->field_count == 0)
2469
This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
2470
prepared statements can't send result set metadata for these queries
2471
on prepare stage. Read it now.
2473
alloc_stmt_fields(stmt);
2478
Update result set metadata if it for some reason changed between
2479
prepare and execute, i.e.:
2480
- in case of 'SELECT ?' we don't know column type unless data was
2481
supplied to mysql_stmt_execute, so updated column type is sent
2483
- if data dictionary changed between prepare and execute, for
2484
example a table used in the query was altered.
2485
Note, that now (4.1.3) we always send metadata in reply to
2486
COM_STMT_EXECUTE (even if it is not necessary), so either this or
2487
previous branch always works.
2488
TODO: send metadata only when it's really necessary and add a warning
2489
'Metadata changed' when it's sent twice.
2491
update_stmt_fields(stmt);
2494
stmt->state= MYSQL_STMT_EXECUTE_DONE;
2495
if (stmt->field_count)
2497
if (stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
2499
mysql->status= MYSQL_STATUS_READY;
2500
stmt->read_row_func= stmt_read_row_from_cursor;
2502
else if (stmt->flags & CURSOR_TYPE_READ_ONLY)
2505
This is a single-row result set, a result set with no rows, EXPLAIN,
2506
SHOW VARIABLES, or some other command which either a) bypasses the
2507
cursors framework in the server and writes rows directly to the
2508
network or b) is more efficient if all (few) result set rows are
2509
precached on client and server's resources are freed.
2511
DBUG_RETURN(mysql_stmt_store_result(stmt));
2515
stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled;
2516
stmt->unbuffered_fetch_cancelled= FALSE;
2517
stmt->read_row_func= stmt_read_row_unbuffered;
2525
Return total parameters count in the statement
2528
ulong STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt)
2530
DBUG_ENTER("mysql_stmt_param_count");
2531
DBUG_RETURN(stmt->param_count);
2535
Return total affected rows from the last statement
2538
my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt)
2540
return stmt->affected_rows;
2545
Returns the number of result columns for the most recent query
2546
run on this statement.
2549
unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt)
2551
return stmt->field_count;
2555
Return last inserted id for auto_increment columns.
2558
mysql_stmt_insert_id()
2559
stmt statement handle
2562
Current implementation of this call has a caveat: stmt->insert_id is
2563
unconditionally updated from mysql->insert_id in the end of each
2564
mysql_stmt_execute(). This works OK if mysql->insert_id contains new
2565
value (sent in reply to mysql_stmt_execute()), otherwise stmt->insert_id
2566
value gets undefined, as it's updated from some arbitrary value saved in
2567
connection structure during some other call.
2570
my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt)
2572
return stmt->insert_id;
1269
2576
static my_bool int_is_null_true= 1; /* Used for MYSQL_TYPE_NULL */
1270
2577
static my_bool int_is_null_false= 0;
2581
Set up input data buffers for a statement.
2584
mysql_stmt_bind_param()
2585
stmt statement handle
2586
The statement must be prepared with mysql_stmt_prepare().
2587
my_bind Array of mysql_stmt_param_count() bind parameters.
2588
This function doesn't check that size of this argument
2589
is >= mysql_stmt_field_count(): it's user's responsibility.
2592
Use this call after mysql_stmt_prepare() to bind user variables to
2594
Each element of bind array stands for a placeholder. Placeholders
2595
are counted from 0. For example statement
2596
'INSERT INTO t (a, b) VALUES (?, ?)'
2597
contains two placeholders, and for such statement you should supply
2598
bind array of two elements (MYSQL_BIND bind[2]).
2600
By properly initializing bind array you can bind virtually any
2601
C language type to statement's placeholders:
2602
First, it's strongly recommended to always zero-initialize entire
2603
bind structure before setting its members. This will both shorten
2604
your application code and make it robust to future extensions of
2605
MYSQL_BIND structure.
2606
Then you need to assign typecode of your application buffer to
2607
MYSQL_BIND::buffer_type. The following typecodes with their
2608
correspondence to C language types are supported:
2609
MYSQL_TYPE_TINY for 8-bit integer variables. Normally it's
2610
'signed char' and 'unsigned char';
2611
MYSQL_TYPE_SHORT for 16-bit signed and unsigned variables. This
2612
is usually 'short' and 'unsigned short';
2613
MYSQL_TYPE_LONG for 32-bit signed and unsigned variables. It
2614
corresponds to 'int' and 'unsigned int' on
2615
vast majority of platforms. On IA-32 and some
2616
other 32-bit systems you can also use 'long'
2618
MYSQL_TYPE_LONGLONG 64-bit signed or unsigned integer. Stands for
2619
'[unsigned] long long' on most platforms;
2620
MYSQL_TYPE_FLOAT 32-bit floating point type, 'float' on most
2622
MYSQL_TYPE_DOUBLE 64-bit floating point type, 'double' on most
2624
MYSQL_TYPE_TIME broken-down time stored in MYSQL_TIME
2626
MYSQL_TYPE_DATE date stored in MYSQL_TIME structure
2627
MYSQL_TYPE_DATETIME datetime stored in MYSQL_TIME structure See
2628
more on how to use these types for sending
2629
dates and times below;
2630
MYSQL_TYPE_STRING character string, assumed to be in
2631
character-set-client. If character set of
2632
client is not equal to character set of
2633
column, value for this placeholder will be
2634
converted to destination character set before
2636
MYSQL_TYPE_BLOB sequence of bytes. This sequence is assumed to
2637
be in binary character set (which is the same
2638
as no particular character set), and is never
2639
converted to any other character set. See also
2640
notes about supplying string/blob length
2642
MYSQL_TYPE_NULL special typecode for binding nulls.
2643
These C/C++ types are not supported yet by the API: long double,
2646
As you can see from the list above, it's responsibility of
2647
application programmer to ensure that chosen typecode properly
2648
corresponds to host language type. For example on all platforms
2649
where we build MySQL packages (as of MySQL 4.1.4) int is a 32-bit
2650
type. So for int you can always assume that proper typecode is
2651
MYSQL_TYPE_LONG (however queer it sounds, the name is legacy of the
2652
old MySQL API). In contrary sizeof(long) can be 4 or 8 8-bit bytes,
2653
depending on platform.
2655
TODO: provide client typedefs for each integer and floating point
2656
typecode, i. e. int8, uint8, float32, etc.
2658
Once typecode was set, it's necessary to assign MYSQL_BIND::buffer
2659
to point to the buffer of given type. Finally, additional actions
2660
may be taken for some types or use cases:
2662
Binding integer types.
2663
For integer types you might also need to set MYSQL_BIND::is_unsigned
2664
member. Set it to TRUE when binding unsigned char, unsigned short,
2665
unsigned int, unsigned long, unsigned long long.
2667
Binding floating point types.
2668
For floating point types you just need to set
2669
MYSQL_BIND::buffer_type and MYSQL_BIND::buffer. The rest of the
2670
members should be zero-initialized.
2673
You might have a column always NULL, never NULL, or sometimes
2674
NULL. For an always NULL column set MYSQL_BIND::buffer_type to
2675
MYSQL_TYPE_NULL. The rest of the members just need to be
2676
zero-initialized. For never NULL columns set
2677
MYSQL_BIND::is_null to 0, or this has already been done if you
2678
zero-initialized the entire structure. If you set
2679
MYSQL_TYPE::is_null to point to an application buffer of type
2680
'my_bool', then this buffer will be checked on each execution:
2681
this way you can set the buffer to TRUE, or any non-0 value for
2682
NULLs, and to FALSE or 0 for not NULL data.
2684
Binding text strings and sequences of bytes.
2685
For strings, in addition to MYSQL_BIND::buffer_type and
2686
MYSQL_BIND::buffer you need to set MYSQL_BIND::length or
2687
MYSQL_BIND::buffer_length. If 'length' is set, 'buffer_length'
2688
is ignored. 'buffer_length' member should be used when size of
2689
string doesn't change between executions. If you want to vary
2690
buffer length for each value, set 'length' to point to an
2691
application buffer of type 'unsigned long' and set this long to
2692
length of the string before each mysql_stmt_execute().
2694
Binding dates and times.
2695
For binding dates and times prepared statements API provides
2696
clients with MYSQL_TIME structure. A pointer to instance of this
2697
structure should be assigned to MYSQL_BIND::buffer whenever
2698
MYSQL_TYPE_TIME, MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME typecodes
2699
are used. When typecode is MYSQL_TYPE_TIME, only members
2700
'hour', 'minute', 'second' and 'neg' (is time offset negative)
2701
are used. These members only will be sent to the server.
2702
MYSQL_TYPE_DATE implies use of 'year', 'month', 'day', 'neg'.
2703
MYSQL_TYPE_DATETIME utilizes both parts of MYSQL_TIME structure.
2704
You don't have to set MYSQL_TIME::time_type member: it's not
2705
used when sending data to the server, typecode information is
2706
enough. 'second_part' member can hold microsecond precision of
2707
time value, but now it's only supported on protocol level: you
2708
can't store microsecond in a column, or use in temporal
2709
calculations. However, if you send a time value with microsecond
2710
part for 'SELECT ?', statement, you'll get it back unchanged
2714
If conversion from host language type to data representation,
2715
corresponding to SQL type, is required it's done on the server.
2716
Data truncation is possible when conversion is lossy. For
2717
example, if you supply MYSQL_TYPE_DATETIME value out of valid
2718
SQL type TIMESTAMP range, the same conversion will be applied as
2719
if this value would have been sent as string in the old
2720
protocol. TODO: document how the server will behave in case of
2721
truncation/data loss.
2723
After variables were bound, you can repeatedly set/change their
2724
values and mysql_stmt_execute() the statement.
2726
See also: mysql_stmt_send_long_data() for sending long text/blob
2727
data in pieces, examples in tests/mysql_client_test.c.
2728
Next steps you might want to make:
2729
- execute statement with mysql_stmt_execute(),
2730
- reset statement using mysql_stmt_reset() or reprepare it with
2731
another query using mysql_stmt_prepare()
2732
- close statement with mysql_stmt_close().
2735
The function copies given bind array to internal storage of the
2736
statement, and sets up typecode-specific handlers to perform
2737
serialization of bound data. This means that although you don't need
2738
to call this routine after each assignment to bind buffers, you
2739
need to call it each time you change parameter typecodes, or other
2740
members of MYSQL_BIND array.
2741
This is a pure local call. Data types of client buffers are sent
2742
along with buffers' data at first execution of the statement.
2746
1 error, can be retrieved with mysql_stmt_error.
2749
my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *my_bind)
2752
MYSQL_BIND *param, *end;
2753
DBUG_ENTER("mysql_stmt_bind_param");
2755
if (!stmt->param_count)
2757
if ((int) stmt->state < (int) MYSQL_STMT_PREPARE_DONE)
2759
set_stmt_error(stmt, CR_NO_PREPARE_STMT, unknown_sqlstate, NULL);
2765
/* Allocated on prepare */
2766
memcpy((char*) stmt->params, (char*) my_bind,
2767
sizeof(MYSQL_BIND) * stmt->param_count);
2769
for (param= stmt->params, end= param+stmt->param_count;
2773
param->param_number= count++;
2774
param->long_data_used= 0;
2776
/* If param->is_null is not set, then the value can never be NULL */
2777
if (!param->is_null)
2778
param->is_null= &int_is_null_false;
2780
/* Setup data copy functions for the different supported types */
2781
switch (param->buffer_type) {
2782
case MYSQL_TYPE_NULL:
2783
param->is_null= &int_is_null_true;
2785
case MYSQL_TYPE_TINY:
2786
/* Force param->length as this is fixed for this type */
2787
param->length= ¶m->buffer_length;
2788
param->buffer_length= 1;
2789
param->store_param_func= store_param_tinyint;
2791
case MYSQL_TYPE_SHORT:
2792
param->length= ¶m->buffer_length;
2793
param->buffer_length= 2;
2794
param->store_param_func= store_param_short;
2796
case MYSQL_TYPE_LONG:
2797
param->length= ¶m->buffer_length;
2798
param->buffer_length= 4;
2799
param->store_param_func= store_param_int32;
2801
case MYSQL_TYPE_LONGLONG:
2802
param->length= ¶m->buffer_length;
2803
param->buffer_length= 8;
2804
param->store_param_func= store_param_int64;
2806
case MYSQL_TYPE_FLOAT:
2807
param->length= ¶m->buffer_length;
2808
param->buffer_length= 4;
2809
param->store_param_func= store_param_float;
2811
case MYSQL_TYPE_DOUBLE:
2812
param->length= ¶m->buffer_length;
2813
param->buffer_length= 8;
2814
param->store_param_func= store_param_double;
2816
case MYSQL_TYPE_TIME:
2817
param->store_param_func= store_param_time;
2818
param->buffer_length= MAX_TIME_REP_LENGTH;
2820
case MYSQL_TYPE_DATE:
2821
param->store_param_func= store_param_date;
2822
param->buffer_length= MAX_DATE_REP_LENGTH;
2824
case MYSQL_TYPE_DATETIME:
2825
case MYSQL_TYPE_TIMESTAMP:
2826
param->store_param_func= store_param_datetime;
2827
param->buffer_length= MAX_DATETIME_REP_LENGTH;
2829
case MYSQL_TYPE_TINY_BLOB:
2830
case MYSQL_TYPE_MEDIUM_BLOB:
2831
case MYSQL_TYPE_LONG_BLOB:
2832
case MYSQL_TYPE_BLOB:
2833
case MYSQL_TYPE_VARCHAR:
2834
case MYSQL_TYPE_VAR_STRING:
2835
case MYSQL_TYPE_STRING:
2836
case MYSQL_TYPE_DECIMAL:
2837
case MYSQL_TYPE_NEWDECIMAL:
2838
param->store_param_func= store_param_str;
2840
For variable length types user must set either length or
2845
strmov(stmt->sqlstate, unknown_sqlstate);
2846
sprintf(stmt->last_error,
2847
ER(stmt->last_errno= CR_UNSUPPORTED_PARAM_TYPE),
2848
param->buffer_type, count);
2852
If param->length is not given, change it to point to buffer_length.
2853
This way we can always use *param->length to get the length of data
2856
param->length= ¶m->buffer_length;
2858
/* We have to send/resend type information to MySQL */
2859
stmt->send_types_to_server= TRUE;
2860
stmt->bind_param_done= TRUE;
2865
/********************************************************************
2866
Long data implementation
2867
*********************************************************************/
2870
Send long data in pieces to the server
2873
mysql_stmt_send_long_data()
2874
stmt Statement handler
2875
param_number Parameter number (0 - N-1)
2876
data Data to send to server
2877
length Length of data to send (may be 0)
2880
This call can be used repeatedly to send long data in pieces
2881
for any string/binary placeholder. Data supplied for
2882
a placeholder is saved at server side till execute, and then
2883
used instead of value from MYSQL_BIND object. More precisely,
2884
if long data for a parameter was supplied, MYSQL_BIND object
2885
corresponding to this parameter is not sent to server. In the
2886
end of execution long data states of placeholders are reset,
2887
so next time values of such placeholders will be taken again
2888
from MYSQL_BIND array.
2889
The server does not reply to this call: if there was an error
2890
in data handling (which now only can happen if server run out
2891
of memory) it would be returned in reply to
2892
mysql_stmt_execute().
2893
You should choose type of long data carefully if you care
2894
about character set conversions performed by server when the
2895
statement is executed. No conversion is performed at all for
2896
MYSQL_TYPE_BLOB and other binary typecodes. For
2897
MYSQL_TYPE_STRING and the rest of text placeholders data is
2898
converted from client character set to character set of
2899
connection. If these character sets are different, this
2900
conversion may require additional memory at server, equal to
2901
total size of supplied pieces.
2909
mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
2910
const char *data, ulong length)
2913
DBUG_ENTER("mysql_stmt_send_long_data");
2914
DBUG_ASSERT(stmt != 0);
2915
DBUG_PRINT("enter",("param no: %d data: 0x%lx, length : %ld",
2916
param_number, (long) data, length));
2919
We only need to check for stmt->param_count, if it's not null
2922
if (param_number >= stmt->param_count)
2924
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate, NULL);
2928
param= stmt->params+param_number;
2929
if (!IS_LONGDATA(param->buffer_type))
2931
/* Long data handling should be used only for string/binary types */
2932
strmov(stmt->sqlstate, unknown_sqlstate);
2933
sprintf(stmt->last_error, ER(stmt->last_errno= CR_INVALID_BUFFER_USE),
2934
param->param_number);
2939
Send long data packet if there is data or we're sending long data
2942
if (length || param->long_data_used == 0)
2944
MYSQL *mysql= stmt->mysql;
2945
/* Packet header: stmt id (4 bytes), param no (2 bytes) */
2946
uchar buff[MYSQL_LONG_DATA_HEADER];
2948
int4store(buff, stmt->stmt_id);
2949
int2store(buff + 4, param_number);
2950
param->long_data_used= 1;
2953
Note that we don't get any ok packet from the server in this case
2954
This is intentional to save bandwidth.
2956
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_SEND_LONG_DATA,
2957
buff, sizeof(buff), (uchar*) data,
2960
set_stmt_errmsg(stmt, &mysql->net);
1272
2968
/********************************************************************
1273
2969
Fetch and conversion of result set rows (binary protocol).
1274
2970
*********************************************************************/
3072
Convert string to supplied buffer of any type.
3075
fetch_string_with_conversion()
3076
param output buffer descriptor
3081
static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
3084
char *buffer= (char *)param->buffer;
3086
char *endptr= value + length;
3089
This function should support all target buffer types: the rest
3090
of conversion functions can delegate conversion to it.
3092
switch (param->buffer_type) {
3093
case MYSQL_TYPE_NULL: /* do nothing */
3095
case MYSQL_TYPE_TINY:
3097
longlong data= my_strtoll10(value, &endptr, &err);
3098
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
3099
INT_MIN8, INT_MAX8, UINT_MAX8) || err > 0);
3100
*buffer= (uchar) data;
3103
case MYSQL_TYPE_SHORT:
3105
longlong data= my_strtoll10(value, &endptr, &err);
3106
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
3107
INT_MIN16, INT_MAX16, UINT_MAX16) || err > 0);
3108
shortstore(buffer, (short) data);
3111
case MYSQL_TYPE_LONG:
3113
longlong data= my_strtoll10(value, &endptr, &err);
3114
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
3115
INT_MIN32, INT_MAX32, UINT_MAX32) || err > 0);
3116
longstore(buffer, (int32) data);
3119
case MYSQL_TYPE_LONGLONG:
3121
longlong data= my_strtoll10(value, &endptr, &err);
3122
*param->error= param->is_unsigned ? err != 0 :
3123
(err > 0 || (err == 0 && data < 0));
3124
longlongstore(buffer, data);
3127
case MYSQL_TYPE_FLOAT:
3129
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
3130
float fdata= (float) data;
3131
*param->error= (fdata != data) | test(err);
3132
floatstore(buffer, fdata);
3135
case MYSQL_TYPE_DOUBLE:
3137
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
3138
*param->error= test(err);
3139
doublestore(buffer, data);
3142
case MYSQL_TYPE_TIME:
3144
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
3145
str_to_time(value, length, tm, &err);
3146
*param->error= test(err);
3149
case MYSQL_TYPE_DATE:
3150
case MYSQL_TYPE_DATETIME:
3151
case MYSQL_TYPE_TIMESTAMP:
3153
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
3154
(void) str_to_datetime(value, length, tm, TIME_FUZZY_DATE, &err);
3155
*param->error= test(err) && (param->buffer_type == MYSQL_TYPE_DATE &&
3156
tm->time_type != MYSQL_TIMESTAMP_DATE);
3159
case MYSQL_TYPE_TINY_BLOB:
3160
case MYSQL_TYPE_MEDIUM_BLOB:
3161
case MYSQL_TYPE_LONG_BLOB:
3162
case MYSQL_TYPE_BLOB:
3163
case MYSQL_TYPE_DECIMAL:
3164
case MYSQL_TYPE_NEWDECIMAL:
3168
Copy column data to the buffer taking into account offset,
3169
data length and buffer length.
3171
char *start= value + param->offset;
3172
char *end= value + length;
3176
copy_length= end - start;
3177
/* We've got some data beyond offset: copy up to buffer_length bytes */
3178
if (param->buffer_length)
3179
memcpy(buffer, start, min(copy_length, param->buffer_length));
3183
if (copy_length < param->buffer_length)
3184
buffer[copy_length]= '\0';
3185
*param->error= copy_length > param->buffer_length;
3187
param->length will always contain length of entire column;
3188
number of copied bytes may be way different:
3190
*param->length= length;
3198
Convert integer value to client buffer of any type.
3201
fetch_long_with_conversion()
3202
param output buffer descriptor
3203
field column metadata
3207
static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
3208
longlong value, my_bool is_unsigned)
3210
char *buffer= (char *)param->buffer;
3212
switch (param->buffer_type) {
3213
case MYSQL_TYPE_NULL: /* do nothing */
3215
case MYSQL_TYPE_TINY:
3216
*param->error= IS_TRUNCATED(value, param->is_unsigned,
3217
INT_MIN8, INT_MAX8, UINT_MAX8);
3218
*(uchar *)param->buffer= (uchar) value;
3220
case MYSQL_TYPE_SHORT:
3221
*param->error= IS_TRUNCATED(value, param->is_unsigned,
3222
INT_MIN16, INT_MAX16, UINT_MAX16);
3223
shortstore(buffer, (short) value);
3225
case MYSQL_TYPE_LONG:
3226
*param->error= IS_TRUNCATED(value, param->is_unsigned,
3227
INT_MIN32, INT_MAX32, UINT_MAX32);
3228
longstore(buffer, (int32) value);
3230
case MYSQL_TYPE_LONGLONG:
3231
longlongstore(buffer, value);
3232
*param->error= param->is_unsigned != is_unsigned && value < 0;
3234
case MYSQL_TYPE_FLOAT:
3237
We need to mark the local variable volatile to
3238
workaround Intel FPU executive precision feature.
3239
(See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details)
3241
volatile float data;
3244
data= (float) ulonglong2double(value);
3245
*param->error= ((ulonglong) value) != ((ulonglong) data);
3250
*param->error= value != ((longlong) data);
3252
floatstore(buffer, data);
3255
case MYSQL_TYPE_DOUBLE:
3257
volatile double data;
3260
data= ulonglong2double(value);
3261
*param->error= ((ulonglong) value) != ((ulonglong) data);
3265
data= (double)value;
3266
*param->error= value != ((longlong) data);
3268
doublestore(buffer, data);
3271
case MYSQL_TYPE_TIME:
3272
case MYSQL_TYPE_DATE:
3273
case MYSQL_TYPE_TIMESTAMP:
3274
case MYSQL_TYPE_DATETIME:
3277
value= number_to_datetime(value, (MYSQL_TIME *) buffer, TIME_FUZZY_DATE,
3279
*param->error= test(error);
3284
uchar buff[22]; /* Enough for longlong */
3285
uchar *end= (uchar*) longlong10_to_str(value, (char*) buff,
3286
is_unsigned ? 10: -10);
3287
/* Resort to string conversion which supports all typecodes */
3288
uint length= (uint) (end-buff);
3290
if (field->flags & ZEROFILL_FLAG && length < field->length &&
3293
bmove_upp(buff+field->length,buff+length, length);
3294
bfill(buff, field->length - length,'0');
3295
length= field->length;
3297
fetch_string_with_conversion(param, (char*) buff, length);
3304
Convert double/float column to supplied buffer of any type.
3307
fetch_float_with_conversion()
3308
param output buffer descriptor
3309
field column metadata
3311
type either MY_GCVT_ARG_FLOAT or MY_GCVT_ARG_DOUBLE.
3312
Affects the maximum number of significant digits
3313
returned by my_gcvt().
3316
static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
3317
double value, my_gcvt_arg_type type)
3319
char *buffer= (char *)param->buffer;
3320
double val64 = (value < 0 ? -floor(-value) : floor(value));
3322
switch (param->buffer_type) {
3323
case MYSQL_TYPE_NULL: /* do nothing */
3325
case MYSQL_TYPE_TINY:
3327
We need to _store_ data in the buffer before the truncation check to
3328
workaround Intel FPU executive precision feature.
3329
(See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 for details)
3330
Sic: AFAIU it does not guarantee to work.
3332
if (param->is_unsigned)
3333
*buffer= (uint8) value;
3335
*buffer= (int8) value;
3336
*param->error= val64 != (param->is_unsigned ? (double)((uint8) *buffer) :
3337
(double)((int8) *buffer));
3339
case MYSQL_TYPE_SHORT:
3340
if (param->is_unsigned)
3342
ushort data= (ushort) value;
3343
shortstore(buffer, data);
3347
short data= (short) value;
3348
shortstore(buffer, data);
3350
*param->error= val64 != (param->is_unsigned ? (double) (*(ushort*) buffer):
3351
(double) (*(short*) buffer));
3353
case MYSQL_TYPE_LONG:
3354
if (param->is_unsigned)
3356
uint32 data= (uint32) value;
3357
longstore(buffer, data);
3361
int32 data= (int32) value;
3362
longstore(buffer, data);
3364
*param->error= val64 != (param->is_unsigned ? (double) (*(uint32*) buffer):
3365
(double) (*(int32*) buffer));
3367
case MYSQL_TYPE_LONGLONG:
3368
if (param->is_unsigned)
3370
ulonglong data= (ulonglong) value;
3371
longlongstore(buffer, data);
3375
longlong data= (longlong) value;
3376
longlongstore(buffer, data);
3378
*param->error= val64 != (param->is_unsigned ?
3379
ulonglong2double(*(ulonglong*) buffer) :
3380
(double) (*(longlong*) buffer));
3382
case MYSQL_TYPE_FLOAT:
3384
float data= (float) value;
3385
floatstore(buffer, data);
3386
*param->error= (*(float*) buffer) != value;
3389
case MYSQL_TYPE_DOUBLE:
3391
doublestore(buffer, value);
3397
Resort to fetch_string_with_conversion: this should handle
3398
floating point -> string conversion nicely, honor all typecodes
3399
and param->offset possibly set in mysql_stmt_fetch_column
3401
char buff[FLOATING_POINT_BUFFER];
3403
if (field->decimals >= NOT_FIXED_DEC)
3404
len= my_gcvt(value, type,
3405
(int) min(sizeof(buff)-1, param->buffer_length),
3408
len= my_fcvt(value, (int) field->decimals, buff, NULL);
3410
if (field->flags & ZEROFILL_FLAG && len < field->length &&
3411
field->length < MAX_DOUBLE_STRING_REP_LENGTH - 1)
3413
bmove_upp((uchar*) buff + field->length, (uchar*) buff + len,
3415
bfill((char*) buff, field->length - len, '0');
3418
fetch_string_with_conversion(param, buff, len);
3427
Fetch time/date/datetime to supplied buffer of any type
3430
param output buffer descriptor
3434
static void fetch_datetime_with_conversion(MYSQL_BIND *param,
3436
MYSQL_TIME *my_time)
3438
switch (param->buffer_type) {
3439
case MYSQL_TYPE_NULL: /* do nothing */
3441
case MYSQL_TYPE_DATE:
3442
*(MYSQL_TIME *)(param->buffer)= *my_time;
3443
*param->error= my_time->time_type != MYSQL_TIMESTAMP_DATE;
3445
case MYSQL_TYPE_TIME:
3446
*(MYSQL_TIME *)(param->buffer)= *my_time;
3447
*param->error= my_time->time_type != MYSQL_TIMESTAMP_TIME;
3449
case MYSQL_TYPE_DATETIME:
3450
case MYSQL_TYPE_TIMESTAMP:
3451
*(MYSQL_TIME *)(param->buffer)= *my_time;
3452
/* No error: time and date are compatible with datetime */
3454
case MYSQL_TYPE_YEAR:
3455
shortstore(param->buffer, my_time->year);
3458
case MYSQL_TYPE_FLOAT:
3459
case MYSQL_TYPE_DOUBLE:
3461
ulonglong value= TIME_to_ulonglong(my_time);
3462
fetch_float_with_conversion(param, field,
3463
ulonglong2double(value), MY_GCVT_ARG_DOUBLE);
3466
case MYSQL_TYPE_TINY:
3467
case MYSQL_TYPE_SHORT:
3468
case MYSQL_TYPE_INT24:
3469
case MYSQL_TYPE_LONG:
3470
case MYSQL_TYPE_LONGLONG:
3472
longlong value= (longlong) TIME_to_ulonglong(my_time);
3473
fetch_long_with_conversion(param, field, value, TRUE);
3479
Convert time value to string and delegate the rest to
3480
fetch_string_with_conversion:
3482
char buff[MAX_DATE_STRING_REP_LENGTH];
3483
uint length= my_TIME_to_str(my_time, buff);
3484
/* Resort to string conversion */
3485
fetch_string_with_conversion(param, (char *)buff, length);
3493
Fetch and convert result set column to output buffer.
3496
fetch_result_with_conversion()
3497
param output buffer descriptor
3498
field column metadata
3499
row points to a column of result set tuple in binary format
3502
This is a fallback implementation of column fetch used
3503
if column and output buffer types do not match.
3504
Increases tuple pointer to point at the next column within the
3508
static void fetch_result_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
3511
enum enum_field_types field_type= field->type;
3512
uint field_is_unsigned= field->flags & UNSIGNED_FLAG;
3514
switch (field_type) {
3515
case MYSQL_TYPE_TINY:
3518
/* sic: we need to cast to 'signed char' as 'char' may be unsigned */
3519
longlong data= field_is_unsigned ? (longlong) value :
3520
(longlong) (signed char) value;
3521
fetch_long_with_conversion(param, field, data, 0);
3525
case MYSQL_TYPE_SHORT:
3526
case MYSQL_TYPE_YEAR:
3528
short value= sint2korr(*row);
3529
longlong data= field_is_unsigned ? (longlong) (unsigned short) value :
3531
fetch_long_with_conversion(param, field, data, 0);
3535
case MYSQL_TYPE_INT24: /* mediumint is sent as 4 bytes int */
3536
case MYSQL_TYPE_LONG:
3538
int32 value= sint4korr(*row);
3539
longlong data= field_is_unsigned ? (longlong) (uint32) value :
3541
fetch_long_with_conversion(param, field, data, 0);
3545
case MYSQL_TYPE_LONGLONG:
3547
longlong value= (longlong)sint8korr(*row);
3548
fetch_long_with_conversion(param, field, value,
3549
field->flags & UNSIGNED_FLAG);
3553
case MYSQL_TYPE_FLOAT:
3556
float4get(value,*row);
3557
fetch_float_with_conversion(param, field, value, MY_GCVT_ARG_FLOAT);
3561
case MYSQL_TYPE_DOUBLE:
3564
float8get(value,*row);
3565
fetch_float_with_conversion(param, field, value, MY_GCVT_ARG_DOUBLE);
3569
case MYSQL_TYPE_DATE:
3573
read_binary_date(&tm, row);
3574
fetch_datetime_with_conversion(param, field, &tm);
3577
case MYSQL_TYPE_TIME:
3581
read_binary_time(&tm, row);
3582
fetch_datetime_with_conversion(param, field, &tm);
3585
case MYSQL_TYPE_DATETIME:
3586
case MYSQL_TYPE_TIMESTAMP:
3590
read_binary_datetime(&tm, row);
3591
fetch_datetime_with_conversion(param, field, &tm);
3596
ulong length= net_field_length(row);
3597
fetch_string_with_conversion(param, (char*) *row, length);
3606
Functions to fetch data to application buffers without conversion.
3608
All functions have the following characteristics:
3612
param MySQL bind param
3616
These are no-conversion functions, used in binary protocol to store
3617
rows in application buffers. A function used only if type of binary data
3618
is compatible with type of application buffer.
3624
static void fetch_result_tinyint(MYSQL_BIND *param, MYSQL_FIELD *field,
3627
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3629
*(uchar *)param->buffer= data;
3630
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX8;
3634
static void fetch_result_short(MYSQL_BIND *param, MYSQL_FIELD *field,
3637
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3638
ushort data= (ushort) sint2korr(*row);
3639
shortstore(param->buffer, data);
3640
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX16;
3644
static void fetch_result_int32(MYSQL_BIND *param,
3645
MYSQL_FIELD *field __attribute__((unused)),
3648
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3649
uint32 data= (uint32) sint4korr(*row);
3650
longstore(param->buffer, data);
3651
*param->error= param->is_unsigned != field_is_unsigned && data > INT_MAX32;
3655
static void fetch_result_int64(MYSQL_BIND *param,
3656
MYSQL_FIELD *field __attribute__((unused)),
3659
my_bool field_is_unsigned= test(field->flags & UNSIGNED_FLAG);
3660
ulonglong data= (ulonglong) sint8korr(*row);
3661
*param->error= param->is_unsigned != field_is_unsigned && data > LONGLONG_MAX;
3662
longlongstore(param->buffer, data);
3666
static void fetch_result_float(MYSQL_BIND *param,
3667
MYSQL_FIELD *field __attribute__((unused)),
3671
float4get(value,*row);
3672
floatstore(param->buffer, value);
3676
static void fetch_result_double(MYSQL_BIND *param,
3677
MYSQL_FIELD *field __attribute__((unused)),
3681
float8get(value,*row);
3682
doublestore(param->buffer, value);
3686
static void fetch_result_time(MYSQL_BIND *param,
3687
MYSQL_FIELD *field __attribute__((unused)),
3690
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
3691
read_binary_time(tm, row);
3694
static void fetch_result_date(MYSQL_BIND *param,
3695
MYSQL_FIELD *field __attribute__((unused)),
3698
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
3699
read_binary_date(tm, row);
3702
static void fetch_result_datetime(MYSQL_BIND *param,
3703
MYSQL_FIELD *field __attribute__((unused)),
3706
MYSQL_TIME *tm= (MYSQL_TIME *)param->buffer;
3707
read_binary_datetime(tm, row);
3710
static void fetch_result_bin(MYSQL_BIND *param,
3711
MYSQL_FIELD *field __attribute__((unused)),
3714
ulong length= net_field_length(row);
3715
ulong copy_length= min(length, param->buffer_length);
3716
memcpy(param->buffer, (char *)*row, copy_length);
3717
*param->length= length;
3718
*param->error= copy_length < length;
3722
static void fetch_result_str(MYSQL_BIND *param,
3723
MYSQL_FIELD *field __attribute__((unused)),
3726
ulong length= net_field_length(row);
3727
ulong copy_length= min(length, param->buffer_length);
3728
memcpy(param->buffer, (char *)*row, copy_length);
3729
/* Add an end null if there is room in the buffer */
3730
if (copy_length != param->buffer_length)
3731
((uchar *)param->buffer)[copy_length]= '\0';
3732
*param->length= length; /* return total length */
3733
*param->error= copy_length < length;
3739
functions to calculate max lengths for strings during
3740
mysql_stmt_store_result()
3743
static void skip_result_fixed(MYSQL_BIND *param,
3744
MYSQL_FIELD *field __attribute__((unused)),
3748
(*row)+= param->pack_length;
3752
static void skip_result_with_length(MYSQL_BIND *param __attribute__((unused)),
3753
MYSQL_FIELD *field __attribute__((unused)),
3757
ulong length= net_field_length(row);
3762
static void skip_result_string(MYSQL_BIND *param __attribute__((unused)),
3767
ulong length= net_field_length(row);
3769
if (field->max_length < length)
3770
field->max_length= length;
1376
3775
Check that two field types are binary compatible i. e.
1377
3776
have equal representation in the binary protocol and
1378
3777
require client-side buffers of the same type.
4143
Fetch and return row data to bound buffers, if any
4146
int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
4150
DBUG_ENTER("mysql_stmt_fetch");
4152
if ((rc= (*stmt->read_row_func)(stmt, &row)) ||
4153
((rc= stmt_fetch_row(stmt, row)) && rc != MYSQL_DATA_TRUNCATED))
4155
stmt->state= MYSQL_STMT_PREPARE_DONE; /* XXX: this is buggy */
4156
stmt->read_row_func= (rc == MYSQL_NO_DATA) ?
4157
stmt_read_row_no_data : stmt_read_row_no_result_set;
4161
/* This is to know in mysql_stmt_fetch_column that data was fetched */
4162
stmt->state= MYSQL_STMT_FETCH_DONE;
4169
Fetch data for one specified column data
4172
mysql_stmt_fetch_column()
4173
stmt Prepared statement handler
4174
my_bind Where data should be placed. Should be filled in as
4175
when calling mysql_stmt_bind_result()
4176
column Column to fetch (first column is 0)
4177
ulong offset Offset in result data (to fetch blob in pieces)
4184
int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *my_bind,
4185
uint column, ulong offset)
4187
MYSQL_BIND *param= stmt->bind+column;
4188
DBUG_ENTER("mysql_stmt_fetch_column");
4190
if ((int) stmt->state < (int) MYSQL_STMT_FETCH_DONE)
4192
set_stmt_error(stmt, CR_NO_DATA, unknown_sqlstate, NULL);
4195
if (column >= stmt->field_count)
4197
set_stmt_error(stmt, CR_INVALID_PARAMETER_NO, unknown_sqlstate, NULL);
4201
if (!my_bind->error)
4202
my_bind->error= &my_bind->error_value;
4206
MYSQL_FIELD *field= stmt->fields+column;
4207
uchar *row= param->row_ptr;
4208
my_bind->offset= offset;
4209
if (my_bind->is_null)
4210
*my_bind->is_null= 0;
4211
if (my_bind->length) /* Set the length if non char/binary types */
4212
*my_bind->length= *param->length;
4214
my_bind->length= ¶m->length_value; /* Needed for fetch_result() */
4215
fetch_result_with_conversion(my_bind, field, &row);
4219
if (my_bind->is_null)
4220
*my_bind->is_null= 1;
4227
Read all rows of data from server (binary format)
4230
int cli_read_binary_rows(MYSQL_STMT *stmt)
4234
MYSQL *mysql= stmt->mysql;
4235
MYSQL_DATA *result= &stmt->result;
4236
MYSQL_ROWS *cur, **prev_ptr= &result->data;
4239
DBUG_ENTER("cli_read_binary_rows");
4243
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
4249
while ((pkt_len= cli_safe_read(mysql)) != packet_error)
4252
if (cp[0] != 254 || pkt_len >= 8)
4254
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
4255
sizeof(MYSQL_ROWS) + pkt_len - 1)))
4257
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
4260
cur->data= (MYSQL_ROW) (cur+1);
4262
prev_ptr= &cur->next;
4263
memcpy((char *) cur->data, (char *) cp+1, pkt_len-1);
4264
cur->length= pkt_len; /* To allow us to do sanity checks */
4271
mysql->warning_count= uint2korr(cp+1);
4272
mysql->server_status= uint2korr(cp+3);
4273
DBUG_PRINT("info",("status: %u warning_count: %u",
4274
mysql->server_status, mysql->warning_count));
4278
set_stmt_errmsg(stmt, net);
4286
Update meta data for statement
4289
stmt_update_metadata()
4290
stmt Statement handler
4294
Only updates MYSQL_FIELD->max_length for strings
4297
static void stmt_update_metadata(MYSQL_STMT *stmt, MYSQL_ROWS *data)
4299
MYSQL_BIND *my_bind, *end;
4301
uchar *null_ptr, bit;
4302
uchar *row= (uchar*) data->data;
4304
uchar *row_end= row + data->length;
4308
row+= (stmt->field_count+9)/8; /* skip null bits */
4309
bit= 4; /* first 2 bits are reserved */
4311
/* Go through all fields and calculate metadata */
4312
for (my_bind= stmt->bind, end= my_bind + stmt->field_count, field= stmt->fields ;
4316
if (!(*null_ptr & bit))
4317
(*my_bind->skip_result)(my_bind, field, &row);
4318
DBUG_ASSERT(row <= row_end);
4319
if (!((bit<<=1) & 255))
4321
bit= 1; /* To next uchar */
4329
Store or buffer the binary results to stmt
4332
int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
4334
MYSQL *mysql= stmt->mysql;
4335
MYSQL_DATA *result= &stmt->result;
4336
DBUG_ENTER("mysql_stmt_store_result");
4340
/* mysql can be reset in mysql_close called from mysql_reconnect */
4341
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
4345
if (!stmt->field_count)
4348
if ((int) stmt->state < (int) MYSQL_STMT_EXECUTE_DONE)
4350
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
4354
if (mysql->status == MYSQL_STATUS_READY &&
4355
stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
4358
Server side cursor exist, tell server to start sending the rows
4360
NET *net= &mysql->net;
4361
uchar buff[4 /* statement id */ +
4362
4 /* number of rows to fetch */];
4364
/* Send row request to the server */
4365
int4store(buff, stmt->stmt_id);
4366
int4store(buff + 4, (int)~0); /* number of rows to fetch */
4367
if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
4368
(uchar*) 0, 0, 1, stmt))
4370
set_stmt_errmsg(stmt, net);
4374
else if (mysql->status != MYSQL_STATUS_GET_RESULT)
4376
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate, NULL);
4380
if (stmt->update_max_length && !stmt->bind_result_done)
4383
We must initalize the bind structure to be able to calculate
4386
MYSQL_BIND *my_bind, *end;
4388
bzero((char*) stmt->bind, sizeof(*stmt->bind)* stmt->field_count);
4390
for (my_bind= stmt->bind, end= my_bind + stmt->field_count,
4391
field= stmt->fields;
4395
my_bind->buffer_type= MYSQL_TYPE_NULL;
4396
my_bind->buffer_length=1;
4399
if (mysql_stmt_bind_result(stmt, stmt->bind))
4401
stmt->bind_result_done= 0; /* No normal bind done */
4404
if ((*mysql->methods->read_binary_rows)(stmt))
4406
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
4409
mysql->status= MYSQL_STATUS_READY;
4413
/* Assert that if there was a cursor, all rows have been fetched */
4414
DBUG_ASSERT(mysql->status != MYSQL_STATUS_READY ||
4415
(mysql->server_status & SERVER_STATUS_LAST_ROW_SENT));
4417
if (stmt->update_max_length)
4419
MYSQL_ROWS *cur= result->data;
4420
for(; cur; cur=cur->next)
4421
stmt_update_metadata(stmt, cur);
4424
stmt->data_cursor= result->data;
4425
mysql->affected_rows= stmt->affected_rows= result->rows;
4426
stmt->read_row_func= stmt_read_row_buffered;
4427
mysql->unbuffered_fetch_owner= 0; /* set in stmt_execute */
4428
mysql->status= MYSQL_STATUS_READY; /* server is ready */
4429
DBUG_RETURN(0); /* Data buffered, must be fetched with mysql_stmt_fetch() */
4434
Seek to desired row in the statement result set
4437
MYSQL_ROW_OFFSET STDCALL
4438
mysql_stmt_row_seek(MYSQL_STMT *stmt, MYSQL_ROW_OFFSET row)
4440
MYSQL_ROW_OFFSET offset= stmt->data_cursor;
4441
DBUG_ENTER("mysql_stmt_row_seek");
4443
stmt->data_cursor= row;
4444
DBUG_RETURN(offset);
4449
Return the current statement row cursor position
4452
MYSQL_ROW_OFFSET STDCALL
4453
mysql_stmt_row_tell(MYSQL_STMT *stmt)
4455
DBUG_ENTER("mysql_stmt_row_tell");
4457
DBUG_RETURN(stmt->data_cursor);
4462
Move the stmt result set data cursor to specified row
4466
mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong row)
4468
MYSQL_ROWS *tmp= stmt->result.data;
4469
DBUG_ENTER("mysql_stmt_data_seek");
4470
DBUG_PRINT("enter",("row id to seek: %ld",(long) row));
4472
for (; tmp && row; --row, tmp= tmp->next)
4474
stmt->data_cursor= tmp;
4477
/* Rewind the counter */
4478
stmt->read_row_func= stmt_read_row_buffered;
4479
stmt->state= MYSQL_STMT_EXECUTE_DONE;
4486
Return total rows the current statement result set
4489
my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt)
4491
DBUG_ENTER("mysql_stmt_num_rows");
4493
DBUG_RETURN(stmt->result.rows);
4498
Free the client side memory buffers, reset long data state
4499
on client if necessary, and reset the server side statement if
4500
this has been requested.
4503
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
4505
/* If statement hasn't been prepared there is nothing to reset */
4506
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
4508
MYSQL *mysql= stmt->mysql;
4509
MYSQL_DATA *result= &stmt->result;
4512
Reset stored result set if so was requested or it's a part
4515
if (flags & RESET_STORE_RESULT)
4517
/* Result buffered */
4518
free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
4521
stmt->data_cursor= NULL;
4523
if (flags & RESET_LONG_DATA)
4525
MYSQL_BIND *param= stmt->params, *param_end= param + stmt->param_count;
4526
/* Clear long_data_used flags */
4527
for (; param < param_end; param++)
4528
param->long_data_used= 0;
4530
stmt->read_row_func= stmt_read_row_no_result_set;
4533
if ((int) stmt->state > (int) MYSQL_STMT_PREPARE_DONE)
4535
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
4536
mysql->unbuffered_fetch_owner= 0;
4537
if (stmt->field_count && mysql->status != MYSQL_STATUS_READY)
4539
/* There is a result set and it belongs to this statement */
4540
(*mysql->methods->flush_use_result)(mysql);
4541
if (mysql->unbuffered_fetch_owner)
4542
*mysql->unbuffered_fetch_owner= TRUE;
4543
mysql->status= MYSQL_STATUS_READY;
4546
if (flags & RESET_SERVER_SIDE)
4549
Reset the server side statement and close the server side
4550
cursor if it exists.
4552
uchar buff[MYSQL_STMT_HEADER]; /* packet header: 4 bytes for stmt id */
4553
int4store(buff, stmt->stmt_id);
4554
if ((*mysql->methods->advanced_command)(mysql, COM_STMT_RESET, buff,
4555
sizeof(buff), 0, 0, 0, stmt))
4557
set_stmt_errmsg(stmt, &mysql->net);
4558
stmt->state= MYSQL_STMT_INIT_DONE;
4561
stmt_clear_error(stmt);
4564
stmt->state= MYSQL_STMT_PREPARE_DONE;
4569
my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
4571
DBUG_ENTER("mysql_stmt_free_result");
4573
/* Free the client side and close the server side cursor if there is one */
4574
DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT));
4577
/********************************************************************
4578
statement error handling and close
4579
*********************************************************************/
4582
Close the statement handle by freeing all alloced resources
4586
stmt Statement handle
4593
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
4595
MYSQL *mysql= stmt->mysql;
4597
DBUG_ENTER("mysql_stmt_close");
4599
free_root(&stmt->result.alloc, MYF(0));
4600
free_root(&stmt->mem_root, MYF(0));
4604
mysql->stmts= list_delete(mysql->stmts, &stmt->list);
4606
Clear NET error state: if the following commands come through
4607
successfully, connection will still be usable for other commands.
4609
net_clear_error(&mysql->net);
4610
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
4612
uchar buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
4614
if (mysql->unbuffered_fetch_owner == &stmt->unbuffered_fetch_cancelled)
4615
mysql->unbuffered_fetch_owner= 0;
4616
if (mysql->status != MYSQL_STATUS_READY)
4619
Flush result set of the connection. If it does not belong
4620
to this statement, set a warning.
4622
(*mysql->methods->flush_use_result)(mysql);
4623
if (mysql->unbuffered_fetch_owner)
4624
*mysql->unbuffered_fetch_owner= TRUE;
4625
mysql->status= MYSQL_STATUS_READY;
4627
int4store(buff, stmt->stmt_id);
4628
if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
4630
set_stmt_errmsg(stmt, &mysql->net);
4635
my_free((uchar*) stmt, MYF(MY_WME));
4637
DBUG_RETURN(test(rc));
4641
Reset the statement buffers in server
4644
my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
4646
DBUG_ENTER("mysql_stmt_reset");
4647
DBUG_ASSERT(stmt != 0);
4650
/* mysql can be reset in mysql_close called from mysql_reconnect */
4651
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate, NULL);
4654
/* Reset the client and server sides of the prepared statement */
4655
DBUG_RETURN(reset_stmt_handle(stmt, RESET_SERVER_SIDE | RESET_LONG_DATA));
4659
Return statement error code
4662
uint STDCALL mysql_stmt_errno(MYSQL_STMT * stmt)
4664
DBUG_ENTER("mysql_stmt_errno");
4665
DBUG_RETURN(stmt->last_errno);
4668
const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt)
4670
DBUG_ENTER("mysql_stmt_sqlstate");
4671
DBUG_RETURN(stmt->sqlstate);
4675
Return statement error message
4678
const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt)
4680
DBUG_ENTER("mysql_stmt_error");
4681
DBUG_RETURN(stmt->last_error);
1433
4685
/********************************************************************
1434
4686
Transactional APIs
1435
4687
*********************************************************************/