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 has_no_value(), has_long_data_value(), has_int_value(), instead of direct access to Item_param::state.
This commit is contained in:
parent
31031a52da
commit
45e40892c5
@ -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));
|
||||
|
@ -2013,6 +2013,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
|
||||
|
||||
#
|
||||
|
69
sql/item.cc
69
sql/item.cc
@ -3309,9 +3309,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)
|
||||
{
|
||||
@ -3338,7 +3338,7 @@ void Item_param::set_null()
|
||||
max_length= 0;
|
||||
decimals= 0;
|
||||
state= NULL_VALUE;
|
||||
item_type= Item::NULL_ITEM;
|
||||
fix_type(Item::NULL_ITEM);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -3350,6 +3350,7 @@ void Item_param::set_int(longlong i, uint32 max_length_arg)
|
||||
max_length= max_length_arg;
|
||||
decimals= 0;
|
||||
maybe_null= 0;
|
||||
fix_type(Item::INT_ITEM);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -3361,6 +3362,7 @@ void Item_param::set_double(double d)
|
||||
max_length= DBL_DIG + 8;
|
||||
decimals= NOT_FIXED_DEC;
|
||||
maybe_null= 0;
|
||||
fix_type(Item::REAL_ITEM);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -3390,21 +3392,41 @@ 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;
|
||||
fix_type(Item::DECIMAL_ITEM);
|
||||
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);
|
||||
fix_type(Item::DECIMAL_ITEM);
|
||||
}
|
||||
|
||||
|
||||
void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg)
|
||||
{
|
||||
state= TIME_VALUE;
|
||||
max_length= max_length_arg;
|
||||
decimals= decimals_arg;
|
||||
fix_type(Item::DATE_ITEM);
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
|
||||
@ -3433,11 +3455,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;
|
||||
}
|
||||
|
||||
@ -3458,6 +3478,7 @@ 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 */
|
||||
fix_type(Item::STRING_ITEM);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -3489,6 +3510,7 @@ bool Item_param::set_longdata(const char *str, ulong length)
|
||||
DBUG_RETURN(TRUE);
|
||||
state= LONG_DATA_VALUE;
|
||||
maybe_null= 0;
|
||||
fix_type(Item::STRING_ITEM);
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
@ -3547,7 +3569,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);
|
||||
}
|
||||
@ -3559,12 +3580,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:
|
||||
@ -3574,7 +3593,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()))
|
||||
@ -3583,24 +3601,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;
|
||||
}
|
||||
@ -3641,6 +3648,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
|
||||
@ -3978,6 +3986,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;
|
||||
@ -4112,6 +4121,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);
|
||||
@ -4123,6 +4133,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
|
||||
@ -4137,6 +4148,7 @@ void Item_param::set_default()
|
||||
void Item_param::set_ignore()
|
||||
{
|
||||
state= IGNORE_VALUE;
|
||||
fixed= true;
|
||||
null_value= true;
|
||||
}
|
||||
|
||||
@ -4182,18 +4194,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:
|
||||
@ -4204,8 +4213,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;
|
||||
}
|
||||
|
||||
@ -4215,7 +4223,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;
|
||||
}
|
||||
|
||||
|
76
sql/item.h
76
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,17 @@ public:
|
||||
DECIMAL_VALUE, DEFAULT_VALUE, IGNORE_VALUE
|
||||
} state;
|
||||
|
||||
enum Type item_type;
|
||||
|
||||
void fix_type(Type type)
|
||||
{
|
||||
item_type= type;
|
||||
fixed= true;
|
||||
}
|
||||
|
||||
void fix_temporal(uint32 max_length_arg, uint decimals_arg);
|
||||
|
||||
public:
|
||||
struct CONVERSION_INFO
|
||||
{
|
||||
/*
|
||||
@ -2838,8 +2889,6 @@ public:
|
||||
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 +2898,11 @@ public:
|
||||
|
||||
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 +2917,11 @@ public:
|
||||
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 +2947,18 @@ public:
|
||||
bool is_null()
|
||||
{ DBUG_ASSERT(state != NO_VALUE); return state == NULL_VALUE; }
|
||||
bool basic_const_item() const;
|
||||
bool has_no_value() const
|
||||
{
|
||||
return state == NO_VALUE;
|
||||
}
|
||||
bool has_long_data_value() const
|
||||
{
|
||||
return state == LONG_DATA_VALUE;
|
||||
}
|
||||
bool has_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
|
||||
|
@ -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->has_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->has_no_value())
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (param->limit_clause_param && param->state != Item_param::INT_VALUE)
|
||||
if (param->limit_clause_param && !param->has_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->has_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->has_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->has_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->has_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->has_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->has_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->has_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->has_no_value())
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user