diff --git a/mysql-test/main/having.result b/mysql-test/main/having.result index f37cc48772e513ac4373b484375885cf163f38a8..233843de36ff32e3fe9f1ec7e53981fb4f650449 100644 --- a/mysql-test/main/having.result +++ b/mysql-test/main/having.result @@ -846,3 +846,36 @@ t r DROP TABLE t1; DROP FUNCTION next_seq_value; DROP TABLE series; +# +# MDEV-24958 Server crashes in my_strtod / +# Value_source::Converter_strntod::Converter_strntod with DEFAULT(blob) +# +# MDEV-24942 Server crashes in _ma_rec_pack / _ma_write_blob_record with +# DEFAULT() on BLOB +# +CREATE TABLE t1 (id INT, f MEDIUMTEXT NOT NULL DEFAULT 'A'); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +SELECT f FROM t1 GROUP BY id ORDER BY DEFAULT(f); +f +foo +bar +SELECT DEFAULT(f) AS h FROM t1 HAVING h > 5; +h +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'A' +SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 0; +h +A +A +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'A' +SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 'A'; +h +A +A +alter table t1 add column b int default (rand()+1+3); +select default(b) AS h FROM t1 HAVING h > "2"; +h +# +# +drop table t1; diff --git a/mysql-test/main/having.test b/mysql-test/main/having.test index 179af14559fefad6cf57e06e81597a850c69635f..8b0cc244f51d4ec2d3767197264654e2d9546c7e 100644 --- a/mysql-test/main/having.test +++ b/mysql-test/main/having.test @@ -890,3 +890,23 @@ SELECT t, next_seq_value() r FROM t1 FORCE INDEX(t) DROP TABLE t1; DROP FUNCTION next_seq_value; DROP TABLE series; + +--echo # +--echo # MDEV-24958 Server crashes in my_strtod / +--echo # Value_source::Converter_strntod::Converter_strntod with DEFAULT(blob) +--echo # +--echo # MDEV-24942 Server crashes in _ma_rec_pack / _ma_write_blob_record with +--echo # DEFAULT() on BLOB +--echo # + +CREATE TABLE t1 (id INT, f MEDIUMTEXT NOT NULL DEFAULT 'A'); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +SELECT f FROM t1 GROUP BY id ORDER BY DEFAULT(f); +SELECT DEFAULT(f) AS h FROM t1 HAVING h > 5; +SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 0; +SELECT DEFAULT(f) AS h FROM t1 HAVING h >= 'A'; + +alter table t1 add column b int default (rand()+1+3); +--replace_column 1 # +select default(b) AS h FROM t1 HAVING h > "2"; +drop table t1; diff --git a/sql/item.cc b/sql/item.cc index 522fef576991f931b056632c6de3c5da91ae7d7c..7b15c7ddb43d2209b2ba283b74049fdffde0a73e 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 9200dd80ee8cf416bf17243f661c73ea92045e72..9fa384f09475e9a729e2f4694a6fc81f72b066ef 100644 --- a/sql/item.h +++ b/sql/item.h @@ -5859,6 +5859,16 @@ class Item_default_value : public Item_field 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 7658d843d8b19638c862e5a85f189509c8e91c23..ce8209469086492340e29cfcc891789e4a972848 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: