diff options
author | Monty <monty@mariadb.org> | 2021-03-01 14:44:18 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2021-03-01 22:09:05 +0200 |
commit | 415409579af68ee2e3c55d5294d7bb5e6397b03f (patch) | |
tree | b60db15f52345496b34afd8288bd0a9f8b8119ba /sql | |
parent | 6983ce704baff7a6e5dd411a289e3580bc7bea1a (diff) | |
download | mariadb-git-415409579af68ee2e3c55d5294d7bb5e6397b03f.tar.gz |
MDEV-24958 Server crashes in my_strtod ... with DEFAULT(blob)
Fixes also:
MDEV-24942 Server crashes in _ma_rec_pack... with DEFAULT() on BLOB
This was caused by two different bugs, both related to that the default
value for the blob was not calculated before it was used:
- There where now Item_default_value::..result() wrappers, which is
needed as item in HAVING uses these. This causes crashes when
using a reference to a DEFAULT(blob_field) in HAVING. It also
caused wrong results when used with other fields with default value
expressions that are not constants.
- create_tmp_field() did not take into account that blob fields with
default expressions are not yet initialized. Fixed by treating
Item_default_value(blob) like a normal item expression.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 47 | ||||
-rw-r--r-- | sql/item.h | 10 | ||||
-rw-r--r-- | sql/sql_select.cc | 24 |
3 files changed, 76 insertions, 5 deletions
diff --git a/sql/item.cc b/sql/item.cc index 522fef57699..7b15c7ddb43 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9341,7 +9341,6 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) } thd->column_usage= save_column_usage; - real_arg= arg->real_item(); if (real_arg->type() != FIELD_ITEM) { @@ -9364,7 +9363,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) def_field->reset_fields(); // If non-constant default value expression or a blob if (def_field->default_value && - (def_field->default_value->flags || def_field->flags & BLOB_FLAG)) + (def_field->default_value->flags || (def_field->flags & BLOB_FLAG))) { uchar *newptr= (uchar*) thd->alloc(1+def_field->pack_length()); if (!newptr) @@ -9461,11 +9460,53 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) return Item_field::save_in_field(field_arg, no_conversions); } +double Item_default_value::val_result() +{ + calculate(); + return Item_field::val_result(); +} + +longlong Item_default_value::val_int_result() +{ + calculate(); + return Item_field::val_int_result(); +} + +String *Item_default_value::str_result(String* tmp) +{ + calculate(); + return Item_field::str_result(tmp); +} + +bool Item_default_value::val_bool_result() +{ + calculate(); + return Item_field::val_bool_result(); +} + +bool Item_default_value::is_null_result() +{ + calculate(); + return Item_field::is_null_result(); +} + +my_decimal *Item_default_value::val_decimal_result(my_decimal *decimal_value) +{ + calculate(); + return Item_field::val_decimal_result(decimal_value); +} + +bool Item_default_value::get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate) +{ + calculate(); + return Item_field::get_date_result(ltime, fuzzydate); +} + table_map Item_default_value::used_tables() const { if (!field || !field->default_value) return static_cast<table_map>(0); - if (!field->default_value->expr) // not fully parsed field + if (!field->default_value->expr) // not fully parsed field return static_cast<table_map>(RAND_TABLE_BIT); return field->default_value->expr->used_tables(); } diff --git a/sql/item.h b/sql/item.h index 9200dd80ee8..9fa384f0947 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5859,6 +5859,16 @@ public: longlong val_int(); my_decimal *val_decimal(my_decimal *decimal_value); bool get_date(MYSQL_TIME *ltime,ulonglong fuzzydate); + + /* Result variants */ + double val_result(); + longlong val_int_result(); + String *str_result(String* tmp); + my_decimal *val_decimal_result(my_decimal *val); + bool val_bool_result(); + bool is_null_result(); + bool get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate); + bool send(Protocol *protocol, st_value *buffer); int save_in_field(Field *field_arg, bool no_conversions); bool save_in_param(THD *thd, Item_param *param) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7658d843d8b..ce820946908 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -17224,7 +17224,13 @@ Field *Item::create_field_for_schema(THD *thd, TABLE *table) the record in the original table. If modify_item is 0 then fill_record() will update the temporary table - + @param table_cant_handle_bit_fields + Set to 1 if the temporary table cannot handle bit + fields. Only set for heap tables when the bit field + is part of an index. + @param make_copy_field + Set when using with rollup when we want to have + an exact copy of the field. @retval 0 on error @retval @@ -17261,8 +17267,22 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR)); return result; } - case Item::FIELD_ITEM: case Item::DEFAULT_VALUE_ITEM: + { + Field *field= ((Item_default_value*) item)->field; + if (field->default_value && (field->flags & BLOB_FLAG)) + { + /* + We have to use a copy function when using a blob with default value + as the we have to calcuate the default value before we can use it. + */ + return create_tmp_field_from_item(thd, item, table, + (make_copy_field ? 0 : copy_func), + modify_item); + } + } + /* Fall through */ + case Item::FIELD_ITEM: case Item::CONTEXTUALLY_TYPED_VALUE_ITEM: case Item::INSERT_VALUE_ITEM: case Item::TRIGGER_FIELD_ITEM: |