maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #10277
Re: Please review MDEV-11134 Assertion `fixed' failed in Item::const_charset_converter(THD*, CHARSET_INFO*, bool, const char*)
Hello Sergei,
On 12/29/2016 05:33 PM, Sergei Golubchik wrote:
> Hi, Alexander!
>
> On Dec 26, Alexander Barkov wrote:
>> Hello Sergei,
>>
>> can you please review a fix for MDEV-11134.
>>
>> I made it the easiest way, just fixed the assert to cover this special
>> case when Item_param::safe_charset_converter() is called from
>> mysql_prepare_create_table().
>
> I thought that normally basic const items are always fixed.
> So, Item_param is an exception? It's basic const, but not fixed?
>
>> But perhaps it can be done in different ways:
>>
>>
>> 1. Do call fix_fields()
>> - Fix mysql_prepare_create_table() to call fix_fields.
>> - Fix Item_param::cleanup() not to set fixed to false.
>>
>> or
>>
>> 2. Sync Item_param::fixed with Item_param::basic_const_item()
>> - Fix Item_param::set_xxx() to set both state=XXX_VALUE and fixed=true.
>> - Fix Item_param::cleanup() not to set fixed to false (like in #1)
>
> Yes, I think it's reasonable. It'll make Item_param behave as other
> basic constants do.
Please find a new version attached.
It makes sure that Item_param::fixed, Item_param::state and
Item_param::item_type are in sync to each other.
Thanks!
>
> Regards,
> Sergei
> Chief Architect MariaDB
> and security@xxxxxxxxxxx
>
commit adf6bb91e349e8983b146cbfcaaa002edff54fe5
Author: Alexander Barkov <bar@xxxxxxxxxxx>
Date: Wed Jan 11 13:42:52 2017 +0400
MDEV-11134 Assertion `fixed' failed in Item::const_charset_converter(THD*, CHARSET_INFO*, bool, const char*)
Problem: Item_param::basic_const_item() returned true when fixed==false.
This unexpected combination made Item::const_charset_converter() crash
on asserts.
Fix:
- Changing all Item_param::set_xxx() to set "fixed" to true.
This fixes the problem.
- Additionally, changing all Item_param::set_xxx() to set
Item_param::item_type, to avoid duplicate code, and for consistency,
to make the code symmetric between different constant types.
Before this patch only set_null() set item_type.
- Moving Item_param::state and Item_param::item_type from public to private,
to make sure easier that these members are in sync with "fixed" and to
each other.
- Adding a new argument "unsigned_arg" to Item::set_decimal(),
and reusing it in two places instead of duplicate code.
- Adding a new method Item_param::fix_temporal() and reusing it in two places.
- Adding methods is_no_value(), is_long_data_value(), is_int_value(),
instead of direct access to Item_param::state.
diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result
index dc7a33d..192d782 100644
--- a/mysql-test/r/default.result
+++ b/mysql-test/r/default.result
@@ -3278,6 +3278,44 @@ INSERT INTO t1 VALUES (1),(2),(3);
EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFAULT,DEFAULT;
ERROR HY000: Default/ignore value is not supported for such parameter usage
DROP TABLE t1;
+#
+# MDEV-11134 Assertion `fixed' failed in Item::const_charset_converter(THD*, CHARSET_INFO*, bool, const char*)
+#
+SET NAMES utf8;
+PREPARE stmt FROM "CREATE OR REPLACE TABLE t1 (c CHAR(8) DEFAULT ?)";
+SET @a='';
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` char(8) DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET @a='A';
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` char(8) DEFAULT 'A'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET @a=_utf8 0xC380;
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` char(8) DEFAULT 'Ã'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET @a=_utf8 0xD18F;
+EXECUTE stmt USING @a;
+ERROR 42000: Invalid default value for 'c'
+EXECUTE stmt USING @a;
+ERROR 42000: Invalid default value for 'c'
+DEALLOCATE PREPARE stmt;
# end of 10.2 test
set sql_mode=ansi_quotes;
create table t1 (a int, b int default (a+1));
diff --git a/mysql-test/t/default.test b/mysql-test/t/default.test
index 41ed161..0a3cafd 100644
--- a/mysql-test/t/default.test
+++ b/mysql-test/t/default.test
@@ -2017,6 +2017,36 @@ EXECUTE IMMEDIATE 'EXPLAIN EXTENDED SELECT * FROM t1 WHERE ?+a<=>?+a' USING DEFA
DROP TABLE t1;
+--echo #
+--echo # MDEV-11134 Assertion `fixed' failed in Item::const_charset_converter(THD*, CHARSET_INFO*, bool, const char*)
+--echo #
+
+SET NAMES utf8;
+PREPARE stmt FROM "CREATE OR REPLACE TABLE t1 (c CHAR(8) DEFAULT ?)";
+SET @a='';
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+SET @a='A';
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+SET @a=_utf8 0xC380; # LATIN CAPITAL LETTER A WITH GRAVE
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+SET @a=_utf8 0xD18F; # Cyrillic letter into a latin1 column
+--error ER_INVALID_DEFAULT
+EXECUTE stmt USING @a;
+--error ER_INVALID_DEFAULT
+EXECUTE stmt USING @a;
+DEALLOCATE PREPARE stmt;
+
+
+
--echo # end of 10.2 test
#
diff --git a/sql/item.cc b/sql/item.cc
index 682f883..344e67b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3302,9 +3302,9 @@ Item_param::Item_param(THD *thd, uint pos_in_query_arg):
Rewritable_query_parameter(pos_in_query_arg, 1),
Type_handler_hybrid_field_type(MYSQL_TYPE_VARCHAR),
state(NO_VALUE),
- indicators(0), indicator(STMT_INDICATOR_NONE),
/* Don't pretend to be a literal unless value for this item is set. */
item_type(PARAM_ITEM),
+ indicators(0), indicator(STMT_INDICATOR_NONE),
set_param_func(default_set_param_func),
m_out_param_info(NULL)
{
@@ -3332,6 +3332,7 @@ void Item_param::set_null()
decimals= 0;
state= NULL_VALUE;
item_type= Item::NULL_ITEM;
+ fixed= true;
DBUG_VOID_RETURN;
}
@@ -3343,6 +3344,8 @@ void Item_param::set_int(longlong i, uint32 max_length_arg)
max_length= max_length_arg;
decimals= 0;
maybe_null= 0;
+ item_type= Item::INT_ITEM;
+ fixed= true;
DBUG_VOID_RETURN;
}
@@ -3354,6 +3357,8 @@ void Item_param::set_double(double d)
max_length= DBL_DIG + 8;
decimals= NOT_FIXED_DEC;
maybe_null= 0;
+ item_type= Item::REAL_ITEM;
+ fixed= true;
DBUG_VOID_RETURN;
}
@@ -3383,21 +3388,44 @@ void Item_param::set_decimal(const char *str, ulong length)
my_decimal_precision_to_length_no_truncation(decimal_value.precision(),
decimals, unsigned_flag);
maybe_null= 0;
+ item_type= Item::DECIMAL_ITEM;
+ fixed= true;
DBUG_VOID_RETURN;
}
-void Item_param::set_decimal(const my_decimal *dv)
+void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg)
{
state= DECIMAL_VALUE;
my_decimal2decimal(dv, &decimal_value);
decimals= (uint8) decimal_value.frac;
- unsigned_flag= !decimal_value.sign();
+ unsigned_flag= unsigned_arg;
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
+ item_type= Item::DECIMAL_ITEM;
+ fixed= true;
+}
+
+
+void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg)
+{
+ state= TIME_VALUE;
+ max_length= max_length_arg;
+ decimals= decimals_arg;
+ item_type= Item::DATE_ITEM;
+ fixed= true;
}
+
+void Item_param::set_time(const MYSQL_TIME *tm,
+ uint32 max_length_arg, uint decimals_arg)
+{
+ value.time= *tm;
+ fix_temporal(max_length_arg, decimals_arg);
+}
+
+
/**
Set parameter value from MYSQL_TIME value.
@@ -3426,11 +3454,9 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type,
&str, time_type, 0);
set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR);
}
-
- state= TIME_VALUE;
maybe_null= 0;
- max_length= max_length_arg;
- decimals= tm->second_part > 0 ? TIME_SECOND_PART_DIGITS : 0;
+ fix_temporal(max_length_arg,
+ tm->second_part > 0 ? TIME_SECOND_PART_DIGITS : 0);
DBUG_VOID_RETURN;
}
@@ -3451,6 +3477,8 @@ bool Item_param::set_str(const char *str, ulong length)
maybe_null= 0;
/* max_length and decimals are set after charset conversion */
/* sic: str may be not null-terminated, don't add DBUG_PRINT here */
+ item_type= Item::STRING_ITEM;
+ fixed= true;
DBUG_RETURN(FALSE);
}
@@ -3482,6 +3510,8 @@ bool Item_param::set_longdata(const char *str, ulong length)
DBUG_RETURN(TRUE);
state= LONG_DATA_VALUE;
maybe_null= 0;
+ item_type= Item::STRING_ITEM;
+ fixed= true;
DBUG_RETURN(FALSE);
}
@@ -3540,7 +3570,6 @@ bool Item_param::set_from_item(THD *thd, Item *item)
{
unsigned_flag= item->unsigned_flag;
set_int(val, MY_INT64_NUM_DECIMAL_DIGITS);
- item_type= Item::INT_ITEM;
set_handler_by_result_type(item->result_type());
DBUG_RETURN(!unsigned_flag && value.integer < 0 ? 1 : 0);
}
@@ -3552,12 +3581,10 @@ bool Item_param::set_from_item(THD *thd, Item *item)
switch (item->cmp_type()) {
case REAL_RESULT:
set_double(tmp.value.m_double);
- item_type= Item::REAL_ITEM;
set_handler_by_field_type(MYSQL_TYPE_DOUBLE);
break;
case INT_RESULT:
set_int(tmp.value.m_longlong, MY_INT64_NUM_DECIMAL_DIGITS);
- item_type= Item::INT_ITEM;
set_handler_by_field_type(MYSQL_TYPE_LONGLONG);
break;
case STRING_RESULT:
@@ -3567,7 +3594,6 @@ bool Item_param::set_from_item(THD *thd, Item *item)
Exact value of max_length is not known unless data is converted to
charset of connection, so we have to set it later.
*/
- item_type= Item::STRING_ITEM;
set_handler_by_field_type(MYSQL_TYPE_VARCHAR);
if (set_str(tmp.m_string.ptr(), tmp.m_string.length()))
@@ -3576,24 +3602,13 @@ bool Item_param::set_from_item(THD *thd, Item *item)
}
case DECIMAL_RESULT:
{
- const my_decimal *ent_value= &tmp.m_decimal;
- my_decimal2decimal(ent_value, &decimal_value);
- state= DECIMAL_VALUE;
- decimals= ent_value->frac;
- max_length=
- my_decimal_precision_to_length_no_truncation(ent_value->precision(),
- decimals, unsigned_flag);
- item_type= Item::DECIMAL_ITEM;
+ set_decimal(&tmp.m_decimal, unsigned_flag);
set_handler_by_field_type(MYSQL_TYPE_NEWDECIMAL);
break;
}
case TIME_RESULT:
{
- value.time= tmp.value.m_time;
- state= TIME_VALUE;
- max_length= item->max_length;
- decimals= item->decimals;
- item_type= Item::DATE_ITEM;
+ set_time(&tmp.value.m_time, item->max_length, item->decimals);
set_handler(item->type_handler());
break;
}
@@ -3634,6 +3649,7 @@ void Item_param::reset()
state= NO_VALUE;
maybe_null= 1;
null_value= 0;
+ fixed= false;
/*
Don't reset item_type to PARAM_ITEM: it's only needed to guard
us from item optimizations at prepare stage, when item doesn't yet
@@ -3971,6 +3987,7 @@ bool Item_param::convert_str_value(THD *thd)
bool Item_param::basic_const_item() const
{
+ DBUG_ASSERT(fixed || state == NO_VALUE);
if (state == NO_VALUE || state == TIME_VALUE)
return FALSE;
return TRUE;
@@ -4105,6 +4122,7 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
maybe_null= src->maybe_null;
null_value= src->null_value;
state= src->state;
+ fixed= src->fixed;
value= src->value;
decimal_value.swap(src->decimal_value);
@@ -4116,6 +4134,7 @@ Item_param::set_param_type_and_swap_value(Item_param *src)
void Item_param::set_default()
{
state= DEFAULT_VALUE;
+ fixed= true;
/*
When Item_param is set to DEFAULT_VALUE:
- its val_str() and val_decimal() return NULL
@@ -4130,6 +4149,7 @@ void Item_param::set_default()
void Item_param::set_ignore()
{
state= IGNORE_VALUE;
+ fixed= true;
null_value= true;
}
@@ -4175,18 +4195,15 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
str_value.charset());
collation.set(str_value.charset(), DERIVATION_COERCIBLE);
decimals= 0;
- item_type= Item::STRING_ITEM;
break;
}
case REAL_RESULT:
set_double(arg->val_real());
- item_type= Item::REAL_ITEM;
break;
case INT_RESULT:
set_int(arg->val_int(), arg->max_length);
- item_type= Item::INT_ITEM;
break;
case DECIMAL_RESULT:
@@ -4197,8 +4214,7 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
if (!dv)
return TRUE;
- set_decimal(dv);
- item_type= Item::DECIMAL_ITEM;
+ set_decimal(dv, !dv->sign());
break;
}
@@ -4208,7 +4224,6 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it)
DBUG_ASSERT(TRUE); // Abort in debug mode.
set_null(); // Set to NULL in release mode.
- item_type= Item::NULL_ITEM;
return FALSE;
}
diff --git a/sql/item.h b/sql/item.h
index 1f3e0f0..893f8de 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -2762,7 +2762,47 @@ class Item_param :public Item_basic_value,
public Rewritable_query_parameter,
public Type_handler_hybrid_field_type
{
-public:
+ /*
+ NO_VALUE is a special value meaning that the parameter has not been
+ assigned yet. Item_param::state is assigned to NO_VALUE in constructor
+ and is used at prepare time.
+
+ 1. At prepare time
+ Item_param::fix_fields() sets "fixed" to true,
+ but as Item_param::state is still NO_VALUE,
+ Item_param::basic_const_item() returns false. This prevents various
+ optimizations to happen at prepare time fix_fields().
+ For example, in this query:
+ PREPARE stmt FROM 'SELECT FORMAT(10000,2,?)';
+ Item_param::basic_const_item() is tested from
+ Item_func_format::fix_length_and_dec().
+
+ 2. At execute time:
+ When Item_param gets a value
+ (or a pseudo-value like DEFAULT_VALUE or IGNORE_VALUE):
+ - Item_param::state changes from NO_VALUE to something else
+ - Item_param::fixed is changed to true
+ All Item_param::set_xxx() make sure to do so.
+ In the state with an assigned value:
+ - Item_param::basic_const_item() returns true
+ - Item::type() returns NULL_ITEM, INT_ITEM, REAL_ITEM, DECIMAL_ITEM,
+ DATE_ITEM, STRING_ITEM, depending on the value assigned.
+ So in this state Item_param behaves in many cases like a literal.
+
+ When Item_param::cleanup() is called:
+ - Item_param::state does not change
+ - Item_param::fixed changes to false
+ Note, this puts Item_param into an inconsistent state:
+ - Item_param::basic_const_item() still returns "true"
+ - Item_param::type() still pretends to be a basic constant Item
+ Both are not expected in combination with fixed==false.
+ However, these methods are not really called in this state,
+ see asserts in Item_param::basic_const_item() and Item_param::type().
+
+ When Item_param::reset() is called:
+ - Item_param::state changes to NO_VALUE
+ - Item_param::fixed changes to false
+ */
enum enum_item_param_state
{
NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
@@ -2770,6 +2810,11 @@ class Item_param :public Item_basic_value,
DECIMAL_VALUE, DEFAULT_VALUE, IGNORE_VALUE
} state;
+ enum Type item_type;
+
+ void fix_temporal(uint32 max_length_arg, uint decimals_arg);
+
+public:
struct CONVERSION_INFO
{
/*
@@ -2838,8 +2883,6 @@ class Item_param :public Item_basic_value,
MYSQL_TIME time;
} value;
- enum Type item_type;
-
enum_field_types field_type() const
{ return Type_handler_hybrid_field_type::field_type(); }
enum Item_result result_type () const
@@ -2849,7 +2892,11 @@ class Item_param :public Item_basic_value,
Item_param(THD *thd, uint pos_in_query_arg);
- enum Type type() const { return item_type; }
+ enum Type type() const
+ {
+ DBUG_ASSERT(fixed || state == NO_VALUE);
+ return item_type;
+ }
double val_real();
longlong val_int();
@@ -2864,10 +2911,11 @@ class Item_param :public Item_basic_value,
void set_int(longlong i, uint32 max_length_arg);
void set_double(double i);
void set_decimal(const char *str, ulong length);
- void set_decimal(const my_decimal *dv);
+ void set_decimal(const my_decimal *dv, bool unsigned_arg);
bool set_str(const char *str, ulong length);
bool set_longdata(const char *str, ulong length);
void set_time(MYSQL_TIME *tm, timestamp_type type, uint32 max_length_arg);
+ void set_time(const MYSQL_TIME *tm, uint32 max_length_arg, uint decimals_arg);
bool set_from_item(THD *thd, Item *item);
void reset();
/*
@@ -2893,6 +2941,18 @@ class Item_param :public Item_basic_value,
bool is_null()
{ DBUG_ASSERT(state != NO_VALUE); return state == NULL_VALUE; }
bool basic_const_item() const;
+ bool is_no_value() const
+ {
+ return state == NO_VALUE;
+ }
+ bool is_long_data_value() const
+ {
+ return state == LONG_DATA_VALUE;
+ }
+ bool is_int_value() const
+ {
+ return state == INT_VALUE;
+ }
/*
This method is used to make a copy of a basic constant item when
propagating constants in the optimizer. The reason to create a new
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index d7a23a4..f592ba0 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -742,45 +742,35 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
switch (param_type) {
case MYSQL_TYPE_TINY:
param->set_param_func= set_param_tiny;
- param->item_type= Item::INT_ITEM;
break;
case MYSQL_TYPE_SHORT:
param->set_param_func= set_param_short;
- param->item_type= Item::INT_ITEM;
break;
case MYSQL_TYPE_LONG:
param->set_param_func= set_param_int32;
- param->item_type= Item::INT_ITEM;
break;
case MYSQL_TYPE_LONGLONG:
param->set_param_func= set_param_int64;
- param->item_type= Item::INT_ITEM;
break;
case MYSQL_TYPE_FLOAT:
param->set_param_func= set_param_float;
- param->item_type= Item::REAL_ITEM;
break;
case MYSQL_TYPE_DOUBLE:
param->set_param_func= set_param_double;
- param->item_type= Item::REAL_ITEM;
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
param->set_param_func= set_param_decimal;
- param->item_type= Item::DECIMAL_ITEM;
break;
case MYSQL_TYPE_TIME:
param->set_param_func= set_param_time;
- param->item_type= Item::STRING_ITEM;
break;
case MYSQL_TYPE_DATE:
param->set_param_func= set_param_date;
- param->item_type= Item::STRING_ITEM;
break;
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
param->set_param_func= set_param_datetime;
- param->item_type= Item::STRING_ITEM;
break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
@@ -792,7 +782,6 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
thd->variables.character_set_client;
DBUG_ASSERT(thd->variables.character_set_client);
param->value.cs_info.final_character_set_of_str_value= &my_charset_bin;
- param->item_type= Item::STRING_ITEM;
break;
default:
/*
@@ -821,7 +810,6 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
Exact value of max_length is not known unless data is converted to
charset of connection, so we have to set it later.
*/
- param->item_type= Item::STRING_ITEM;
}
}
param->set_handler_by_field_type((enum enum_field_types) param_type);
@@ -892,7 +880,7 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
for (Item_param **it= begin; it < end; ++it)
{
Item_param *param= *it;
- if (param->state != Item_param::LONG_DATA_VALUE)
+ if (!param->is_long_data_value())
{
if (is_param_null(null_array, (uint) (it - begin)))
param->set_null();
@@ -901,13 +889,12 @@ static bool insert_params_with_log(Prepared_statement *stmt, uchar *null_array,
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
- if (param->state == Item_param::NO_VALUE)
+ if (param->is_no_value())
DBUG_RETURN(1);
- if (param->limit_clause_param && param->state != Item_param::INT_VALUE)
+ if (param->limit_clause_param && !param->is_int_value())
{
param->set_int(param->val_int(), MY_INT64_NUM_DECIMAL_DIGITS);
- param->item_type= Item::INT_ITEM;
if (!param->unsigned_flag && param->value.integer < 0)
DBUG_RETURN(1);
}
@@ -947,7 +934,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
for (Item_param **it= begin; it < end; ++it)
{
Item_param *param= *it;
- if (param->state != Item_param::LONG_DATA_VALUE)
+ if (!param->is_long_data_value())
{
if (is_param_null(null_array, (uint) (it - begin)))
param->set_null();
@@ -956,7 +943,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array,
if (read_pos >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, &read_pos, (uint) (data_end - read_pos));
- if (param->state == Item_param::NO_VALUE)
+ if (param->is_no_value())
DBUG_RETURN(1);
}
}
@@ -989,7 +976,7 @@ static bool insert_bulk_params(Prepared_statement *stmt,
Item_param *param= *it;
if (reset)
param->reset();
- if (param->state != Item_param::LONG_DATA_VALUE)
+ if (!param->is_long_data_value())
{
if (param->indicators)
param->indicator= (enum_indicator_type) *((*read_pos)++);
@@ -1003,7 +990,7 @@ static bool insert_bulk_params(Prepared_statement *stmt,
if ((*read_pos) >= data_end)
DBUG_RETURN(1);
param->set_param_func(param, read_pos, (uint) (data_end - (*read_pos)));
- if (param->state == Item_param::NO_VALUE)
+ if (param->is_no_value())
DBUG_RETURN(1);
break;
case STMT_INDICATOR_NULL:
@@ -1093,7 +1080,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
{
Item_param *param= *it;
setup_one_conversion_function(thd, param, client_param->buffer_type);
- if (param->state != Item_param::LONG_DATA_VALUE)
+ if (!param->is_long_data_value())
{
if (*client_param->is_null)
param->set_null();
@@ -1105,7 +1092,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query)
client_param->length ?
*client_param->length :
client_param->buffer_length);
- if (param->state == Item_param::NO_VALUE)
+ if (param->is_no_value())
DBUG_RETURN(1);
}
}
@@ -1129,7 +1116,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query)
{
Item_param *param= *it;
setup_one_conversion_function(thd, param, client_param->buffer_type);
- if (param->state != Item_param::LONG_DATA_VALUE)
+ if (!param->is_long_data_value())
{
if (*client_param->is_null)
param->set_null();
@@ -1141,7 +1128,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query)
client_param->length ?
*client_param->length :
client_param->buffer_length);
- if (param->state == Item_param::NO_VALUE)
+ if (param->is_no_value())
DBUG_RETURN(1);
}
}
Follow ups
References