summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2017-05-04 11:41:34 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2017-05-16 16:18:11 +0200
commitc37345f0ab223b4ff2c6fc847802eb74645c0fd3 (patch)
treeca869241dc526864a17aa11e86d095cc91379f28
parent58c9b425c50ee68d0750f8d4e72c6172c1dbf7ec (diff)
downloadmariadb-git-bb-10.2-MDEV-12471.tar.gz
Postreview changes.bb-10.2-MDEV-12471
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item.h4
-rw-r--r--sql/sql_insert.cc1
-rw-r--r--sql/sql_prepare.cc115
-rw-r--r--sql/sql_prepare.h2
5 files changed, 73 insertions, 51 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 7f29915c965..e8cfe974a54 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3346,7 +3346,7 @@ Item_param::Item_param(THD *thd, uint pos_in_query_arg):
state(NO_VALUE),
/* Don't pretend to be a literal unless value for this item is set. */
item_type(PARAM_ITEM),
- indicators(0), indicator(STMT_INDICATOR_NONE),
+ indicator(STMT_INDICATOR_NONE),
set_param_func(default_set_param_func),
m_out_param_info(NULL),
/*
diff --git a/sql/item.h b/sql/item.h
index 42e9fd94331..5ed3e8acb82 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2873,10 +2873,8 @@ public:
};
/*
- Used for bulk protocol. Indicates if we should expect
- indicators byte before value of the parameter
+ Used for bulk protocol only.
*/
- my_bool indicators;
enum enum_indicator_type indicator;
/*
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 0049c1dc58b..24e4c07fdb9 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -939,7 +939,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
do
{
DBUG_PRINT("info", ("iteration %llu", iteration));
- /* for 0 iteration parameters are already set */
if (iteration && bulk_parameters_set(thd))
goto abort;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index a790a81944f..feddf1b21f8 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -184,6 +184,7 @@ public:
char last_error[MYSQL_ERRMSG_SIZE];
my_bool iterations;
my_bool start_param;
+ my_bool read_types;
#ifndef EMBEDDED_LIBRARY
bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end,
uchar *read_pos, String *expanded_query);
@@ -934,6 +935,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
for (Item_param **it= begin; it < end; ++it)
{
Item_param *param= *it;
+ param->indicator= STMT_INDICATOR_NONE; // only for bulk parameters
if (!param->has_long_data_value())
{
if (is_param_null(null_array, (uint) (it - begin)))
@@ -978,10 +980,7 @@ static bool insert_bulk_params(Prepared_statement *stmt,
param->reset();
if (!param->has_long_data_value())
{
- if (param->indicators)
- param->indicator= (enum_indicator_type) *((*read_pos)++);
- else
- param->indicator= STMT_INDICATOR_NONE;
+ param->indicator= (enum_indicator_type) *((*read_pos)++);
if ((*read_pos) > data_end)
DBUG_RETURN(1);
switch (param->indicator)
@@ -992,6 +991,8 @@ static bool insert_bulk_params(Prepared_statement *stmt,
param->set_param_func(param, read_pos, (uint) (data_end - (*read_pos)));
if (param->has_no_value())
DBUG_RETURN(1);
+ if (param->convert_str_value(stmt->thd))
+ DBUG_RETURN(1); /* out of memory */
break;
case STMT_INDICATOR_NULL:
param->set_null();
@@ -1010,6 +1011,36 @@ static bool insert_bulk_params(Prepared_statement *stmt,
DBUG_RETURN(0);
}
+static bool set_conversion_functions(Prepared_statement *stmt,
+ uchar **data, uchar *data_end)
+{
+ uchar *read_pos= *data;
+ const uint signed_bit= 1 << 15;
+ DBUG_ENTER("set_conversion_functions");
+ /*
+ First execute or types altered by the client, setup the
+ conversion routines for all parameters (one time)
+ */
+ Item_param **it= stmt->param_array;
+ Item_param **end= it + stmt->param_count;
+ THD *thd= stmt->thd;
+ for (; it < end; ++it)
+ {
+ ushort typecode;
+
+ if (read_pos >= data_end)
+ DBUG_RETURN(1);
+
+ typecode= sint2korr(read_pos);
+ read_pos+= 2;
+ (**it).unsigned_flag= MY_TEST(typecode & signed_bit);
+ setup_one_conversion_function(thd, *it, (uchar) (typecode & 0xff));
+ }
+ *data= read_pos;
+ DBUG_RETURN(0);
+}
+
+
static bool setup_conversion_functions(Prepared_statement *stmt,
uchar **data, uchar *data_end,
bool bulk_protocol= 0)
@@ -1023,29 +1054,9 @@ static bool setup_conversion_functions(Prepared_statement *stmt,
if (*read_pos++) //types supplied / first execute
{
- const uint signed_bit= 1 << 15;
- /*
- First execute or types altered by the client, setup the
- conversion routines for all parameters (one time)
- */
- Item_param **it= stmt->param_array;
- Item_param **end= it + stmt->param_count;
- THD *thd= stmt->thd;
- for (; it < end; ++it)
- {
- ushort typecode;
-
- if (read_pos >= data_end)
- DBUG_RETURN(1);
-
- typecode= sint2korr(read_pos);
- read_pos+= 2;
- (**it).unsigned_flag= MY_TEST(typecode & signed_bit);
- if (bulk_protocol)
- (**it).indicators= TRUE;
- setup_one_conversion_function(thd, *it,
- (uchar) (typecode & 0xff));
- }
+ *data= read_pos;
+ bool res= set_conversion_functions(stmt, data, data_end);
+ DBUG_RETURN(res);
}
*data= read_pos;
DBUG_RETURN(0);
@@ -3035,7 +3046,8 @@ static void mysql_stmt_execute_common(THD *thd,
uchar *packet,
uchar *packet_end,
ulong cursor_flags,
- bool iteration);
+ bool iteration,
+ bool types);
/**
COM_STMT_EXECUTE handler: execute a previously prepared statement.
@@ -3064,7 +3076,8 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
packet+= 9; /* stmt_id + 5 bytes of flags */
- mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, flags, FALSE);
+ mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, flags, FALSE,
+ FALSE);
DBUG_VOID_RETURN;
}
@@ -3090,7 +3103,7 @@ void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
{
uchar *packet= (uchar*)packet_arg; // GCC 4.0.1 workaround
ulong stmt_id= uint4korr(packet);
- ulong flags= (ulong) uint2korr(packet + 4);
+ uint flags= (uint) uint2korr(packet + 4);
uchar *packet_end= packet + packet_length;
DBUG_ENTER("mysqld_stmt_execute_bulk");
@@ -3104,19 +3117,14 @@ void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
/* Check for implemented parameters */
if (flags & (~STMT_BULK_FLAG_CLIENT_SEND_TYPES))
{
- DBUG_PRINT("error", ("unsupported bulk execute flags %lx", flags));
+ DBUG_PRINT("error", ("unsupported bulk execute flags %x", flags));
my_error(ER_UNSUPPORTED_PS, MYF(0));
}
- /* stmt id and one byte of flegs (other will be used for emulation) */
- packet+= 4 + 2 - 1;
- /*
- Emulate all command buffer, where there was a bit before parameter
- which tell if there is type following
- */
- packet[0]= MY_TEST(flags & STMT_BULK_FLAG_CLIENT_SEND_TYPES);
-
- mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, 0, TRUE);
+ /* stmt id and two bytes of flags */
+ packet+= 4 + 2;
+ mysql_stmt_execute_common(thd, stmt_id, packet, packet_end, 0, TRUE,
+ (flags & STMT_BULK_FLAG_CLIENT_SEND_TYPES));
DBUG_VOID_RETURN;
}
@@ -3129,7 +3137,8 @@ void mysqld_stmt_bulk_execute(THD *thd, char *packet_arg, uint packet_length)
@param paket packet with parameters to bind
@param packet_end pointer to the byte after parameters end
@param cursor_flags cursor flags
- @param bulk_op
+ @param bulk_op id it bulk operation
+ @param read_types flag say that types muast been read
*/
static void mysql_stmt_execute_common(THD *thd,
@@ -3137,7 +3146,8 @@ static void mysql_stmt_execute_common(THD *thd,
uchar *packet,
uchar *packet_end,
ulong cursor_flags,
- bool bulk_op)
+ bool bulk_op,
+ bool read_types)
{
/* Query text for binary, general or slow log, if any of them is open */
String expanded_query;
@@ -3145,6 +3155,7 @@ static void mysql_stmt_execute_common(THD *thd,
Protocol *save_protocol= thd->protocol;
bool open_cursor;
DBUG_ENTER("mysqld_stmt_execute_common");
+ DBUG_ASSERT((!read_types) || (read_types && bulk_op));
/* First of all clear possible warnings from the previous command */
thd->reset_for_next_command();
@@ -3156,6 +3167,7 @@ static void mysql_stmt_execute_common(THD *thd,
llstr(stmt_id, llbuf), "mysqld_stmt_execute");
DBUG_VOID_RETURN;
}
+ stmt->read_types= read_types;
#if defined(ENABLED_PROFILING)
thd->profiling.set_query_source(stmt->query(), stmt->query_length());
@@ -3681,6 +3693,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
flags((uint) IS_IN_USE),
iterations(0),
start_param(0),
+ read_types(0),
m_sql_mode(thd->variables.sql_mode)
{
init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size,
@@ -3717,7 +3730,7 @@ void Prepared_statement::setup_set_params()
set_params_from_actual_params= insert_params_from_actual_params_with_log;
#ifndef EMBEDDED_LIBRARY
set_params= insert_params_with_log;
- set_bulk_params= insert_bulk_params; // TODO: add binlog support
+ set_bulk_params= insert_bulk_params; // RBR is on for bulk operation
#else
//TODO: add bulk support for bulk parameters
set_params_data= emb_insert_params_with_log;
@@ -4202,7 +4215,7 @@ my_bool bulk_parameters_set(THD *thd)
DBUG_RETURN(FALSE);
}
-ulong bulk_parameters_iterations(THD *thd)
+my_bool bulk_parameters_iterations(THD *thd)
{
Prepared_statement *stmt= (Prepared_statement *) thd->bulk_param;
if (!stmt)
@@ -4215,6 +4228,7 @@ my_bool Prepared_statement::set_bulk_parameters(bool reset)
{
DBUG_ENTER("Prepared_statement::set_bulk_parameters");
DBUG_PRINT("info", ("iteration: %d", iterations));
+
if (iterations)
{
#ifndef EMBEDDED_LIBRARY
@@ -4259,16 +4273,26 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
thd->set_bulk_execution(0);
return TRUE;
}
+ /* Check for non zero parameter count*/
+ if (param_count == 0)
+ {
+ DBUG_PRINT("error", ("Statement with no parameters for bulk execution."));
+ my_error(ER_UNSUPPORTED_PS, MYF(0));
+ thd->set_bulk_execution(0);
+ return TRUE;
+ }
if (!(sql_command_flags[lex->sql_command] & CF_SP_BULK_SAFE))
{
+ DBUG_PRINT("error", ("Command is not supported in bulk execution."));
my_error(ER_UNSUPPORTED_PS, MYF(0));
thd->set_bulk_execution(0);
return TRUE;
}
#ifndef EMBEDDED_LIBRARY
- if (setup_conversion_functions(this, &packet, packet_end, TRUE))
+ if (read_types &&
+ set_conversion_functions(this, &packet, packet_end))
#else
// bulk parameters are not supported for embedded, so it will an error
#endif
@@ -4279,6 +4303,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
thd->set_bulk_execution(0);
return true;
}
+ read_types= FALSE;
#ifdef NOT_YET_FROM_MYSQL_5_6
if (unlikely(thd->security_ctx->password_expired &&
diff --git a/sql/sql_prepare.h b/sql/sql_prepare.h
index dcd094031c4..203b37b3b26 100644
--- a/sql/sql_prepare.h
+++ b/sql/sql_prepare.h
@@ -84,7 +84,7 @@ void mysqld_stmt_reset(THD *thd, char *packet);
void mysql_stmt_get_longdata(THD *thd, char *pos, ulong packet_length);
void reinit_stmt_before_use(THD *thd, LEX *lex);
-ulong bulk_parameters_iterations(THD *thd);
+my_bool bulk_parameters_iterations(THD *thd);
my_bool bulk_parameters_set(THD *thd);
/**
Execute a fragment of server code in an isolated context, so that