1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Fix for remaining issues described in Bug #1664

"mysql_send_long_data() API call is completely broken".

Now we are resetting some members (long_data_supplied/null_value...) of Item_param to its 
initial state after each execution of prepared statement. We also manipulating 
Item_param::maybe_null/null_value only via Item_param::set_* setters which makes code a bit 
more robust.


sql/item.cc:
  Now we are assuming that Item_param may be NULL until we know this fact exactly.
  Added non-empty implementation of Item_param::reset() method which should be used
  for restoring Item_param state after each statment execution. (We need to clear 
  long_data_supplied flag, we also clear some other Item_param members here since it
  makes code simpler.)
sql/item.h:
  Now Item_param::reset() method really does something.
sql/sql_prepare.cc:
  Now we are calling Item_param::reset() for each parameter after execution for resetting Item_param
  to initial state. So we no longer don't need Prepared_statement::long_data_flag. We also 
  set Item_param::null_value/maybe_null value in Item_param::set_* and reset() methods 
  instead of doing it explicitly in insert_params_* functions (this by the way lowers 
  probability that we will forget to update one of such functions).
tests/client_test.c:
  Added test for Bug#1664 "mysql_send_long_data() API call is broken".
This commit is contained in:
unknown
2004-05-04 19:08:19 +04:00
parent 258a3d1678
commit 6ca757544b
4 changed files with 211 additions and 22 deletions

View File

@ -91,7 +91,6 @@ public:
uint last_errno;
char last_error[MYSQL_ERRMSG_SIZE];
bool get_longdata_error;
bool long_data_used;
bool log_full_query;
#ifndef EMBEDDED_LIBRARY
bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end,
@ -465,12 +464,11 @@ static bool insert_params_withlog(Prepared_statement *stmt, uchar *null_array,
{
if (is_param_null(null_array, it - begin))
{
param->maybe_null= param->null_value= param->value_is_set= 1;
param->set_null();
res= &my_null_string;
}
else
{
param->maybe_null= param->null_value= 0;
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, data_end - read_pos);
@ -503,10 +501,9 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
if (!param->long_data_supplied)
{
if (is_param_null(null_array, it - begin))
param->maybe_null= param->null_value= param->value_is_set= 1;
param->set_null();
else
{
param->maybe_null= param->null_value= 0;
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, data_end - read_pos);
@ -562,11 +559,10 @@ static bool emb_insert_params(Prepared_statement *stmt)
if (!param->long_data_supplied)
{
if (*client_param->is_null)
param->maybe_null= param->null_value= 1;
param->set_null();
else
{
uchar *buff= (uchar*)client_param->buffer;
param->maybe_null= param->null_value= 0;
param->set_param_func(param, &buff,
client_param->length ?
*client_param->length :
@ -604,13 +600,12 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt)
{
if (*client_param->is_null)
{
param->maybe_null= param->null_value= 1;
param->set_null();
res= &my_null_string;
}
else
{
uchar *buff= (uchar*)client_param->buffer;
param->maybe_null= param->null_value= 0;
param->set_param_func(param, &buff,
client_param->length ?
*client_param->length :
@ -1439,6 +1434,24 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
}
}
/*
Clears parameters from data left from previous execution or long data
SYNOPSIS
reset_stmt_params()
stmt - prepared statement for which parameters should be reset
*/
static void reset_stmt_params(Prepared_statement *stmt)
{
Item_param **item= stmt->param_array;
Item_param **end= item + stmt->param_count;
for (;item < end ; ++item)
(**item).reset();
}
/*
Executes previously prepared query.
If there is any parameters, then replace markers with the data supplied
@ -1512,11 +1525,13 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
cleanup_items(stmt->free_list);
reset_stmt_params(stmt);
close_thread_tables(thd); // to close derived tables
thd->set_statement(&thd->stmt_backup);
DBUG_VOID_RETURN;
set_params_data_err:
reset_stmt_params(stmt);
thd->set_statement(&thd->stmt_backup);
my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_execute");
send_error(thd);
@ -1552,15 +1567,12 @@ void mysql_stmt_reset(THD *thd, char *packet)
stmt->get_longdata_error= 0;
/* Free long data if used */
if (stmt->long_data_used)
{
Item_param **item= stmt->param_array;
Item_param **end= item + stmt->param_count;
stmt->long_data_used= 0;
for (; item < end ; item++)
(**item).reset();
}
/*
Clear parameters from data which could be set by
mysql_stmt_send_long_data() call.
*/
reset_stmt_params(stmt);
DBUG_VOID_RETURN;
}
@ -1646,7 +1658,6 @@ void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length)
#else
param->set_longdata(thd->extra_data, thd->extra_length);
#endif
stmt->long_data_used= 1;
DBUG_VOID_RETURN;
}
@ -1658,7 +1669,6 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
param_count(0),
last_errno(0),
get_longdata_error(0),
long_data_used(0),
log_full_query(0)
{
*last_error= '\0';