diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-01-23 22:25:29 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-01-23 22:25:29 +0400 |
commit | 45e40892c5bcd541cd93aebe8ba15b7a27289621 (patch) | |
tree | 3a971e0b3c0301fab7bb2e410c2088f6c13dfd24 /sql/sql_prepare.cc | |
parent | 31031a52da6e88d27c3149b06d9beb9704d0b96c (diff) | |
download | mariadb-git-45e40892c5bcd541cd93aebe8ba15b7a27289621.tar.gz |
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.
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 35 |
1 files changed, 11 insertions, 24 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d7a23a41002..735bdb73d58 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->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); } } |