1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

Fix for CONC-198: can't use two statements per connection

If we have multiple open cursors we need to check the server_status per statement (not per connection)
This commit is contained in:
Georg Richter
2016-08-18 08:04:46 +02:00
parent b68843a93d
commit 405bb926e9
2 changed files with 193 additions and 110 deletions

View File

@@ -13,7 +13,7 @@
You should have received a copy of the GNU Library General Public
License along with this library; if not see <http://www.gnu.org/licenses>
or write to the Free Software Foundation, Inc.,
or write to the Free Software Foundation, Inc.,
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
Part of this code includes code from the PHP project which
@@ -21,7 +21,7 @@
*****************************************************************************/
/* The implementation for prepared statements was ported from PHP's mysqlnd
extension, written by Andrey Hristov, Georg Richter and Ulf Wendel
extension, written by Andrey Hristov, Georg Richter and Ulf Wendel
Original file header:
+----------------------------------------------------------------------+
@@ -196,7 +196,7 @@ int mthd_stmt_read_all_rows(MYSQL_STMT *stmt)
cp++; /* skip first byte */
null_ptr= cp;
cp+= (stmt->field_count + 9) / 8;
for (i=0; i < stmt->field_count; i++)
{
if (!(*null_ptr & bit_offset))
@@ -234,7 +234,7 @@ int mthd_stmt_read_all_rows(MYSQL_STMT *stmt)
}
}
current->length= packet_len;
result->rows++;
result->rows++;
} else /* end of stream */
{
*pprevious= 0;
@@ -242,14 +242,14 @@ int mthd_stmt_read_all_rows(MYSQL_STMT *stmt)
p++;
stmt->upsert_status.warning_count= stmt->mysql->warning_count= uint2korr(p);
p+=2;
stmt->mysql->server_status= uint2korr(p);
stmt->result_cursor= result->data;
stmt->upsert_status.server_status= stmt->mysql->server_status= uint2korr(p);
stmt->result_cursor= result->data;
return(0);
}
}
stmt->result_cursor= 0;
SET_CLIENT_STMT_ERROR(stmt, stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate,
stmt->mysql->net.last_error);
stmt->mysql->net.last_error);
return(1);
}
@@ -269,7 +269,7 @@ static int stmt_cursor_fetch(MYSQL_STMT *stmt, uchar **row)
return(stmt_buffered_fetch(stmt, row));
if (stmt->mysql->server_status & SERVER_STATUS_LAST_ROW_SENT)
stmt->mysql->server_status&= ~SERVER_STATUS_LAST_ROW_SENT;
else
if (!(stmt->upsert_status.server_status & SERVER_STATUS_LAST_ROW_SENT))
{
int4store(buf, stmt->stmt_id);
int4store(buf + STMT_ID_LENGTH, stmt->prefetch_rows);
@@ -280,7 +280,7 @@ static int stmt_cursor_fetch(MYSQL_STMT *stmt, uchar **row)
/* free previously allocated buffer */
ma_free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
result->data= 0;
result->rows= 0;
result->rows= 0;
if (stmt->mysql->methods->db_stmt_read_all_rows(stmt))
return(1);
@@ -321,12 +321,12 @@ int mthd_stmt_fetch_to_bind(MYSQL_STMT *stmt, unsigned char *row)
*stmt->bind[i].is_null= 1;
stmt->bind[i].u.row_ptr= NULL;
} else
{
{
stmt->bind[i].u.row_ptr= row;
if (stmt->bind[i].flags & MADB_BIND_DUMMY)
{
unsigned long length;
if (mysql_ps_fetch_functions[stmt->fields[i].type].pack_len >= 0)
length= mysql_ps_fetch_functions[stmt->fields[i].type].pack_len;
else
@@ -468,8 +468,8 @@ int store_param(MYSQL_STMT *stmt, int column, unsigned char **p, unsigned long r
t_buffer[1]= t->neg ? 1 : 0;
int4store(t_buffer + 2, t->day);
t_buffer[6]= (uchar) t->hour;
t_buffer[7]= (uchar) t->minute;
t_buffer[6]= (uchar) t->hour;
t_buffer[7]= (uchar) t->minute;
t_buffer[8]= (uchar) t->second;
if (t->second_part)
{
@@ -497,7 +497,7 @@ int store_param(MYSQL_STMT *stmt, int column, unsigned char **p, unsigned long r
6 1 minute
7 1 second
8-11 4 secondpart
*/
*/
MYSQL_TIME *t= (MYSQL_TIME *)ma_get_buffer_offset(stmt, stmt->params[column].buffer_type,
stmt->params[column].buffer, row_nr);
char t_buffer[MAX_DATETIME_STR_LEN];
@@ -582,7 +582,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
1st byte: parameter type
2nd byte flag:
unsigned flag (32768)
indicator variable exists (16384)
indicator variable exists (16384)
------------------------------------------
Pre 10.2 protocol
n data from bind_buffer
@@ -590,7 +590,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
if indicator variable exists
1st byte: indicator variable
2nd-n: data
*/
size_t length= 1024;
@@ -640,7 +640,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
memset(p, 0, null_count);
p += null_count;
}
int1store(p, stmt->send_types_to_server);
int1store(p, stmt->send_types_to_server);
p++;
free_bytes= length - (p - start);
@@ -665,7 +665,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
/* check if parameter requires indicator variable */
if (bulk_supported && stmt->params[i].u.indicator)
buffer_type|= 16384;
int2store(p, buffer_type);
int2store(p, buffer_type);
p+= 2;
}
}
@@ -691,7 +691,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
has_data= FALSE;
size= 1;
}
if (stmt->params[i].long_data_used)
{
has_data= FALSE;
@@ -749,7 +749,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
}
if (!stmt->array_size)
{
if ((stmt->params[i].is_null && *stmt->params[i].is_null) ||
if ((stmt->params[i].is_null && *stmt->params[i].is_null) ||
stmt->params[i].buffer_type == MYSQL_TYPE_NULL ||
!stmt->params[i].buffer)
{
@@ -780,7 +780,7 @@ mem_error:
*******************************************************************************
\fn unsigned long long mysql_stmt_affected_rows
\brief returns the number of affected rows from last mysql_stmt_execute
\brief returns the number of affected rows from last mysql_stmt_execute
call
\param[in] stmt The statement handle
@@ -915,15 +915,15 @@ my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT *stmt, MYSQL_BIND *bind)
break;
case MYSQL_TYPE_TINY:
stmt->params[i].buffer_length= 1;
break;
break;
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_YEAR:
stmt->params[i].buffer_length= 2;
break;
break;
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_FLOAT:
stmt->params[i].buffer_length= 4;
break;
break;
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_DOUBLE:
stmt->params[i].buffer_length= 8;
@@ -973,13 +973,13 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
if (!stmt->field_count)
{
SET_CLIENT_STMT_ERROR(stmt, CR_NO_STMT_METADATA, SQLSTATE_UNKNOWN, 0);
return(1);
return(1);
}
if (!bind)
return(1);
/* In case of a stored procedure we don't allocate memory for bind
/* In case of a stored procedure we don't allocate memory for bind
in mysql_stmt_prepare
*/
@@ -990,7 +990,7 @@ my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT *stmt, MYSQL_BIND *bind)
if (!(stmt->bind= (MYSQL_BIND *)ma_alloc_root(fields_ma_alloc_root, stmt->field_count * sizeof(MYSQL_BIND))))
{
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return(1);
return(1);
}
}
@@ -1076,10 +1076,10 @@ static my_bool net_stmt_close(MYSQL_STMT *stmt, my_bool remove)
if (stmt->state > MYSQL_STMT_INITTED)
{
int4store(stmt_id, stmt->stmt_id);
if (stmt->mysql->methods->db_command(stmt->mysql,COM_STMT_CLOSE, stmt_id,
if (stmt->mysql->methods->db_command(stmt->mysql,COM_STMT_CLOSE, stmt_id,
sizeof(stmt_id), 1, stmt))
{
SET_CLIENT_STMT_ERROR(stmt, stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate, stmt->mysql->net.last_error);
SET_CLIENT_STMT_ERROR(stmt, stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate, stmt->mysql->net.last_error);
return 1;
}
}
@@ -1089,7 +1089,7 @@ static my_bool net_stmt_close(MYSQL_STMT *stmt, my_bool remove)
my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
{
if (stmt && stmt->mysql && stmt->mysql->net.pvio)
if (stmt && stmt->mysql && stmt->mysql->net.vio)
mysql_stmt_internal_reset(stmt, 1);
net_stmt_close(stmt, 1);
@@ -1134,7 +1134,7 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
unsigned char *row;
int rc;
if (stmt->state <= MYSQL_STMT_EXECUTED)
if (stmt->state <= MYSQL_STMT_EXECUTED)
{
SET_CLIENT_STMT_ERROR(stmt, CR_COMMANDS_OUT_OF_SYNC, SQLSTATE_UNKNOWN, 0);
return(1);
@@ -1173,7 +1173,7 @@ int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt)
int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind, unsigned int column, unsigned long offset)
{
if (stmt->state < MYSQL_STMT_USER_FETCHING || column >= stmt->field_count ||
if (stmt->state < MYSQL_STMT_USER_FETCHING || column >= stmt->field_count ||
stmt->state == MYSQL_STMT_FETCH_DONE) {
SET_CLIENT_STMT_ERROR(stmt, CR_NO_DATA, SQLSTATE_UNKNOWN, 0);
return(1);
@@ -1214,7 +1214,7 @@ unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt)
my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
{
return madb_reset_stmt(stmt, MADB_RESET_LONGDATA | MADB_RESET_STORED |
return madb_reset_stmt(stmt, MADB_RESET_LONGDATA | MADB_RESET_STORED |
MADB_RESET_BUFFER | MADB_RESET_ERROR);
}
@@ -1230,7 +1230,7 @@ MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql)
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return(NULL);
}
/* fill mysql's stmt list */
stmt->list.data= stmt;
@@ -1305,7 +1305,7 @@ my_bool mthd_stmt_get_result_metadata(MYSQL_STMT *stmt)
if (!(stmt->fields= unpack_fields(result,fields_ma_alloc_root,
stmt->field_count, 0,
stmt->mysql->server_capabilities & CLIENT_LONG_FLAG)))
return(1);
return(1);
return(0);
}
@@ -1316,7 +1316,7 @@ int STDCALL mysql_stmt_warning_count(MYSQL_STMT *stmt)
int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, size_t length)
{
MYSQL *mysql= stmt->mysql;
MYSQL *mysql= stmt->mysql;
int rc= 1;
enum mariadb_com_multi multi= MARIADB_COM_MULTI_END;
@@ -1355,7 +1355,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, size_t lengt
stmt->field_count= 0;
int4store(stmt_id, stmt->stmt_id);
if (mysql->methods->db_command(mysql, COM_STMT_CLOSE, stmt_id,
if (mysql->methods->db_command(mysql, COM_STMT_CLOSE, stmt_id,
sizeof(stmt_id), 1, stmt))
goto fail;
}
@@ -1378,7 +1378,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, size_t lengt
}
/* allocated bind buffer for parameters */
if (stmt->field_count &&
if (stmt->field_count &&
stmt->mysql->methods->db_stmt_get_result_metadata(stmt))
{
goto fail;
@@ -1388,7 +1388,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, size_t lengt
if (!(stmt->params= (MYSQL_BIND *)ma_alloc_root(&stmt->mem_root, stmt->param_count * sizeof(MYSQL_BIND))))
{
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
goto fail;
goto fail;
}
memset(stmt->params, '\0', stmt->param_count * sizeof(MYSQL_BIND));
}
@@ -1399,7 +1399,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, size_t lengt
if (!(stmt->bind= (MYSQL_BIND *)ma_alloc_root(fields_ma_alloc_root, stmt->field_count * sizeof(MYSQL_BIND))))
{
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
goto fail;
goto fail;
}
}
stmt->state = MYSQL_STMT_PREPARED;
@@ -1408,7 +1408,7 @@ int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, size_t lengt
fail:
stmt->state= MYSQL_STMT_INITTED;
SET_CLIENT_STMT_ERROR(stmt, mysql->net.last_errno, mysql->net.sqlstate,
mysql->net.last_error);
mysql->net.last_error);
return(rc);
}
@@ -1445,7 +1445,7 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
int4store(buff, stmt->stmt_id);
int4store(buff + STMT_ID_LENGTH, (int)~0);
if (stmt->mysql->methods->db_command(stmt->mysql, COM_STMT_FETCH,
if (stmt->mysql->methods->db_command(stmt->mysql, COM_STMT_FETCH,
buff, sizeof(buff), 1, stmt))
return(1);
/* todo: cursor */
@@ -1544,11 +1544,11 @@ int stmt_read_execute_response(MYSQL_STMT *stmt)
{
MYSQL *mysql= stmt->mysql;
int ret;
if (!mysql)
return(1);
ret= test((mysql->methods->db_read_stmt_result &&
ret= test((mysql->methods->db_read_stmt_result &&
mysql->methods->db_read_stmt_result(mysql)));
/* if a reconnect occured, our connection handle is invalid */
if (!stmt->mysql)
@@ -1718,9 +1718,9 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
}
request= (char *)mysql_stmt_execute_generate_request(stmt, &request_len);
ret= stmt->mysql->methods->db_command(mysql, COM_STMT_EXECUTE, request,
ret= stmt->mysql->methods->db_command(mysql, COM_STMT_EXECUTE, request,
request_len, 1, stmt);
if (request)
free(request);
@@ -1784,14 +1784,14 @@ static my_bool madb_reset_stmt(MYSQL_STMT *stmt, unsigned int flags)
{
mysql->methods->db_stmt_flush_unbuffered(stmt);
mysql->status= MYSQL_STATUS_READY;
}
}
}
if (flags & MADB_RESET_SERVER)
{
/* reset statement on server side */
if (stmt->mysql && stmt->mysql->status == MYSQL_STATUS_READY &&
stmt->mysql->net.pvio)
stmt->mysql->net.vio)
{
unsigned char cmd_buf[STMT_ID_LENGTH];
int4store(cmd_buf, stmt->stmt_id);
@@ -1831,7 +1831,7 @@ static my_bool mysql_stmt_internal_reset(MYSQL_STMT *stmt, my_bool is_close)
/* connection could be invalid, e.g. after mysql_stmt_close or failed reconnect
attempt (see bug CONC-97) */
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0);
return(1);
return(1);
}
if (stmt->state >= MYSQL_STMT_USER_FETCHING &&
@@ -1855,9 +1855,9 @@ static my_bool mysql_stmt_internal_reset(MYSQL_STMT *stmt, my_bool is_close)
if (stmt->field_count)
{
while (mysql_stmt_next_result(stmt) == 0);
while (mysql_stmt_next_result(stmt) == 0);
stmt->mysql->status= MYSQL_STATUS_READY;
}
}
}
if (!is_close)
ret= madb_reset_stmt(stmt, MADB_RESET_SERVER);
@@ -1868,7 +1868,7 @@ static my_bool mysql_stmt_internal_reset(MYSQL_STMT *stmt, my_bool is_close)
stmt->upsert_status.server_status= mysql->server_status;
stmt->upsert_status.warning_count= mysql->warning_count;
mysql->status= MYSQL_STATUS_READY;
return(ret);
}
@@ -1888,7 +1888,7 @@ MYSQL_RES * STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt)
res->eof= 1;
res->fields= stmt->fields;
res->field_count= stmt->field_count;
res->field_count= stmt->field_count;
return(res);
}
@@ -1952,8 +1952,8 @@ my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number,
ret= stmt->mysql->methods->db_command(stmt->mysql, COM_STMT_SEND_LONG_DATA,
(char *)cmd_buff, packet_len, 1, stmt);
free(cmd_buff);
return(ret);
}
return(ret);
}
return(0);
}
@@ -1985,7 +1985,7 @@ my_bool STDCALL mysql_stmt_more_results(MYSQL_STMT *stmt)
return (stmt &&
stmt->mysql &&
((stmt->mysql->server_status & SERVER_MORE_RESULTS_EXIST) ||
(stmt->mysql->server_status & SERVER_PS_OUT_PARAMS)));
(stmt->mysql->server_status & SERVER_PS_OUT_PARAMS)));
}
int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt)
@@ -2008,9 +2008,9 @@ int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt)
if (!mysql_stmt_more_results(stmt))
return(-1);
if (stmt->state > MYSQL_STMT_EXECUTED &&
if (stmt->state > MYSQL_STMT_EXECUTED &&
stmt->state < MYSQL_STMT_FETCH_DONE)
madb_reset_stmt(stmt, MADB_RESET_ERROR | MADB_RESET_BUFFER | MADB_RESET_LONGDATA);
madb_reset_stmt(stmt, MADB_RESET_ERROR | MADB_RESET_BUFFER | MADB_RESET_LONGDATA);
stmt->state= MYSQL_STMT_WAITING_USE_OR_STORE;
if (mysql_next_result(stmt->mysql))
@@ -2087,7 +2087,7 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
stmt->field_count= 0;
int4store(stmt_id, stmt->stmt_id);
if (mysql->methods->db_command(mysql, COM_STMT_CLOSE, stmt_id,
if (mysql->methods->db_command(mysql, COM_STMT_CLOSE, stmt_id,
sizeof(stmt_id), 1, stmt))
goto fail;
}
@@ -2120,7 +2120,7 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
}
/* allocated bind buffer for parameters */
if (stmt->field_count &&
if (stmt->field_count &&
stmt->mysql->methods->db_stmt_get_result_metadata(stmt))
{
goto fail;
@@ -2133,7 +2133,7 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
if (!(stmt->bind= (MYSQL_BIND *)ma_alloc_root(fields_ma_alloc_root, stmt->field_count * sizeof(MYSQL_BIND))))
{
SET_CLIENT_STMT_ERROR(stmt, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
goto fail;
goto fail;
}
}
stmt->state = MYSQL_STMT_PREPARED;
@@ -2143,6 +2143,6 @@ int STDCALL mariadb_stmt_execute_direct(MYSQL_STMT *stmt,
fail:
stmt->state= MYSQL_STMT_INITTED;
SET_CLIENT_STMT_ERROR(stmt, mysql->net.last_errno, mysql->net.sqlstate,
mysql->net.last_error);
mysql->net.last_error);
return 1;
}

View File

@@ -61,7 +61,7 @@ static int test_conc67(MYSQL *mysql)
check_stmt_rc(rc, stmt);
rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, &prefetch_rows);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_prepare(stmt, query, strlen(query));
check_stmt_rc(rc, stmt);
@@ -77,7 +77,7 @@ static int test_conc67(MYSQL *mysql)
res= mysql_stmt_result_metadata(stmt);
mysql_free_result(res);
memset(bind, 0, 2 * sizeof(MYSQL_BIND));
i= 0;
@@ -261,7 +261,7 @@ static int test_bug1180(MYSQL *mysql)
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
rowcount= 0;
while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
rowcount++;
@@ -528,9 +528,9 @@ static int test_bug12744(MYSQL *mysql)
rc= mysql_options(mysql, MYSQL_OPT_RECONNECT, "1");
check_mysql_rc(rc, mysql);
rc= mysql_kill(mysql, mysql_thread_id(mysql));
sleep(4);
rc= mysql_ping(mysql);
rc= mysql_ping(mysql);
check_mysql_rc(rc, mysql);
rc= mysql_stmt_close(stmt);
@@ -1293,7 +1293,7 @@ static int test_bug23383(MYSQL *mysql)
rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query));
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
check_stmt_rc(rc, stmt);
row_count= mysql_stmt_affected_rows(stmt);
FAIL_UNLESS(row_count == 2, "row_count != 2");
@@ -1305,7 +1305,7 @@ static int test_bug23383(MYSQL *mysql)
rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query));
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
check_stmt_rc(rc, stmt);
row_count= mysql_stmt_affected_rows(stmt);
FAIL_UNLESS(row_count == 0, "rowcount != 0");
@@ -1901,22 +1901,22 @@ static int test_ps_query_cache(MYSQL *mysql)
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
r_metadata= mysql_stmt_result_metadata(stmt);
FAIL_UNLESS(r_metadata != NULL, "");
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt);
FAIL_UNLESS((r_int_data == 1) && (r_str_length == 2) &&
r_metadata= mysql_stmt_result_metadata(stmt);
FAIL_UNLESS(r_metadata != NULL, "");
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt);
FAIL_UNLESS((r_int_data == 1) && (r_str_length == 2) &&
(strcmp(r_str_data, "hh") == 0), "test_ps_query_cache_result failure"); \
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt);
FAIL_UNLESS((r_int_data == 2) && (r_str_length == 2) &&
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt);
FAIL_UNLESS((r_int_data == 2) && (r_str_length == 2) &&
(strcmp(r_str_data, "hh") == 0), "test_ps_query_cache_result failure"); \
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt);
FAIL_UNLESS((r_int_data == 1) && (r_str_length == 2) &&
rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt);
FAIL_UNLESS((r_int_data == 1) && (r_str_length == 2) &&
(strcmp(r_str_data, "ii") == 0), "test_ps_query_cache_result failure"); \
rc= mysql_stmt_fetch(stmt);
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
rc= mysql_stmt_fetch(stmt);
FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
mysql_free_result(r_metadata);
@@ -2184,8 +2184,8 @@ static int test_bug4026(MYSQL *mysql)
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
check_stmt_rc(rc, stmt);
/* Bind input buffers */
memset(my_bind, '\0', sizeof(MYSQL_BIND) * 2);
memset(&time_in, '\0', sizeof(MYSQL_TIME));
memset(my_bind, '\0', sizeof(MYSQL_BIND) * 2);
memset(&time_in, '\0', sizeof(MYSQL_TIME));
memset(&time_out, '\0', sizeof(MYSQL_TIME));
memset(&datetime_in, '\0', sizeof(MYSQL_TIME));
memset(&datetime_out, '\0', sizeof(MYSQL_TIME));
@@ -2247,7 +2247,7 @@ static int test_bug4030(MYSQL *mysql)
stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
"'2003-12-31 23:59:59.123456'";
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
check_stmt_rc(rc, stmt);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
/* Bind output buffers */
@@ -2476,14 +2476,14 @@ static int test_bug4236(MYSQL *mysql)
stmt1= mysql_stmt_init(mysql1);
stmt_text= "SELECT 2";
rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
check_stmt_rc(rc, stmt);
check_stmt_rc(rc, stmt);
stmt->stmt_id= stmt1->stmt_id;
rc= mysql_stmt_execute(stmt);
FAIL_IF(!rc, "Error expected");
mysql_stmt_close(stmt1);
mysql_close(mysql1);
mysql_close(mysql1);
/* Restore original statement id to be able to reprepare it */
stmt->stmt_id= backup.stmt_id;
@@ -2516,7 +2516,7 @@ static int test_bug5126(MYSQL *mysql)
stmt= mysql_stmt_init(mysql);
stmt_text= "SELECT a, b FROM t1";
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
check_stmt_rc(rc, stmt);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
/* Bind output buffers */
@@ -2722,7 +2722,7 @@ static int test_bug5315(MYSQL *mysql)
rc= mysql_stmt_execute(stmt);
FAIL_UNLESS(rc != 0, "Error expected");
rc= mysql_stmt_close(stmt);
check_stmt_rc(rc, stmt);
@@ -2741,7 +2741,7 @@ static int test_bug5399(MYSQL *mysql)
Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
statement id hash in the server uses binary collation.
*/
#define NUM_OF_USED_STMT 97
#define NUM_OF_USED_STMT 97
MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
MYSQL_STMT **stmt;
MYSQL_BIND my_bind[1];
@@ -3344,7 +3344,7 @@ static int test_decimal_bug(MYSQL *mysql)
stmt= mysql_stmt_init(mysql);
FAIL_IF(!stmt, mysql_error(mysql));
rc= mysql_stmt_prepare(stmt, "select c1 from test_decimal_bug where c1=?",
rc= mysql_stmt_prepare(stmt, "select c1 from test_decimal_bug where c1=?",
strlen("select c1 from test_decimal_bug where c1=?"));
check_stmt_rc(rc, stmt);
@@ -3460,13 +3460,13 @@ static int test_explain_bug(MYSQL *mysql)
if (verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
0, 0,
0, 0,
mysql_get_server_version(mysql) <= 50400 ? "" : "information_schema",
64, 0))
goto error;
if (verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
0, 0,
0, 0,
mysql_get_server_version(mysql) <= 50400 ? "" : "information_schema",
0, 0))
goto error;
@@ -3474,7 +3474,7 @@ static int test_explain_bug(MYSQL *mysql)
if (verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
0, 0,
0, 0,
mysql_get_server_version(mysql) <= 50400 ? "" : "information_schema",
3, 0))
goto error;
@@ -3482,7 +3482,7 @@ static int test_explain_bug(MYSQL *mysql)
if (verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
0, 0,
0, 0,
mysql_get_server_version(mysql) <= 50400 ? "" : "information_schema",
3, 0))
goto error;
@@ -3491,7 +3491,7 @@ static int test_explain_bug(MYSQL *mysql)
{
/* The patch for bug#23037 changes column type of DEAULT to blob */
if (verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
MYSQL_TYPE_BLOB, 0, 0,
MYSQL_TYPE_BLOB, 0, 0,
mysql_get_server_version(mysql) <= 50400 ? "" : "information_schema",
0, 0))
goto error;
@@ -3503,7 +3503,7 @@ static int test_explain_bug(MYSQL *mysql)
MYSQL_TYPE_BLOB :
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
0, 0,
0, 0,
mysql_get_server_version(mysql) <= 50400 ? "" : "information_schema",
mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0))
goto error;
@@ -3512,7 +3512,7 @@ static int test_explain_bug(MYSQL *mysql)
if (verify_prepare_field(result, 5, "Extra", "EXTRA",
mysql_get_server_version(mysql) <= 50000 ?
MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
0, 0,
0, 0,
mysql_get_server_version(mysql) <= 50400 ? "" : "information_schema",
27, 0))
goto error;
@@ -3572,7 +3572,7 @@ static int test_explain_bug(MYSQL *mysql)
goto error;
}
if (verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING, "", "", "",
if (verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING, "", "", "",
NAME_CHAR_LEN*16, 0))
goto error;
@@ -3754,10 +3754,10 @@ static int test_bug53311(MYSQL *mysql)
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug53311");
check_mysql_rc(rc, mysql);
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE bug53311 (a int)");
check_mysql_rc(rc, mysql);
check_mysql_rc(rc, mysql);
stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, query, strlen(query));
@@ -3768,7 +3768,7 @@ static int test_bug53311(MYSQL *mysql)
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
}
/* kill connection */
rc= mysql_kill(mysql, mysql_thread_id(mysql));
sleep(1);
@@ -4332,8 +4332,91 @@ static int test_conc181(MYSQL *mysql)
return OK;
}
static int test_conc198(MYSQL *mysql)
{
MYSQL_STMT *stmt1, *stmt2;
MYSQL_BIND my_bind[1];
int32 a;
int rc;
const char *stmt_text;
int num_rows= 0;
ulong type;
ulong prefetch_rows= 3;
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (id integer not null primary key)");
rc= mysql_query(mysql, "insert into t1 (id) values "
" (1), (2), (3), (4), (5), (6), (7), (8), (9)");
check_mysql_rc(rc, mysql);
stmt1= mysql_stmt_init(mysql);
stmt2= mysql_stmt_init(mysql);
/* Not implemented in 5.0 */
type= (ulong) CURSOR_TYPE_SCROLLABLE;
rc= mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (void*) &type);
FAIL_UNLESS(rc, "Error expected");
rc= mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (void*) &type);
FAIL_UNLESS(rc, "Error expected");
type= (ulong) CURSOR_TYPE_READ_ONLY;
rc= mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (void*) &type);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (void*) &type);
check_stmt_rc(rc, stmt2);
rc= mysql_stmt_attr_set(stmt1, STMT_ATTR_PREFETCH_ROWS,
(void*) &prefetch_rows);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_attr_set(stmt2, STMT_ATTR_PREFETCH_ROWS,
(void*) &prefetch_rows);
check_stmt_rc(rc, stmt2);
stmt_text= "select * from t1";
rc= mysql_stmt_prepare(stmt1, "SELECT * FROM t1 ORDER by id ASC" , -1);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_prepare(stmt2, "SELECT * FROM t1 ORDER by id DESC", -1);
check_stmt_rc(rc, stmt2);
rc= mysql_stmt_execute(stmt1);
check_stmt_rc(rc, stmt1);
rc= mysql_stmt_execute(stmt2);
check_stmt_rc(rc, stmt2);
memset(my_bind, '\0', sizeof(my_bind));
my_bind[0].buffer_type= MYSQL_TYPE_LONG;
my_bind[0].buffer= (void*) &a;
my_bind[0].buffer_length= sizeof(a);
mysql_stmt_bind_result(stmt1, my_bind);
mysql_stmt_bind_result(stmt2, my_bind);
while ((rc= mysql_stmt_fetch(stmt1)) == 0)
{
diag("a=%d", a);
++num_rows;
}
FAIL_UNLESS(num_rows == 9, "num_rows != 9");
diag("---------------");
num_rows= 0;
while ((rc= mysql_stmt_fetch(stmt2)) == 0)
{
diag("a=%d", a);
++num_rows;
}
FAIL_UNLESS(num_rows == 9, "num_rows != 9");
rc= mysql_stmt_close(stmt1);
rc= mysql_stmt_close(stmt2);
FAIL_UNLESS(rc == 0, "");
rc= mysql_query(mysql, "drop table t1");
check_mysql_rc(rc, mysql);
return OK;
}
struct my_tests_st my_tests[] = {
{"test_conc198", test_conc198, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc182", test_conc182, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc181", test_conc181, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc179", test_conc179, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
@@ -4355,12 +4438,12 @@ struct my_tests_st my_tests[] = {
{"test_bug15510", test_bug15510, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug15518", test_bug15518, TEST_CONNECTION_NEW | TEST_CONNECTION_DONT_CLOSE, CLIENT_MULTI_STATEMENTS, NULL , NULL},
{"test_bug15613", test_bug15613, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug16144", test_bug16144, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug16144", test_bug16144, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug1664", test_bug1664, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug1946", test_bug1946, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug2247", test_bug2247, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug2248", test_bug2248, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug20152", test_bug20152, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug20152", test_bug20152, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug23383", test_bug23383, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug27592", test_bug27592, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug28934", test_bug28934, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
@@ -4374,8 +4457,8 @@ struct my_tests_st my_tests[] = {
{"test_bug4172", test_bug4172, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug4231", test_bug4231, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug4236", test_bug4236, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug5126", test_bug5126, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug5194", test_bug5194, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug5126", test_bug5126, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug5194", test_bug5194, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug5315", test_bug5315, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug5399", test_bug5399, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug6046", test_bug6046, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
@@ -4390,13 +4473,13 @@ struct my_tests_st my_tests[] = {
{"test_ps_null_param", test_ps_null_param, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_ps_query_cache", test_ps_query_cache, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_ushort_bug", test_ushort_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_field_misc", test_field_misc, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_mem_overun", test_mem_overun, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_field_misc", test_field_misc, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_mem_overun", test_mem_overun, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_decimal_bug", test_decimal_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_explain_bug", test_explain_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_sshort_bug", test_sshort_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_stiny_bug", test_stiny_bug, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_bug53311", test_bug53311, TEST_CONNECTION_NEW, 0, NULL , NULL},
{"test_bug53311", test_bug53311, TEST_CONNECTION_NEW, 0, NULL , NULL},
{NULL, NULL, 0, 0, NULL, NULL}
};