diff --git a/mysql-test/main/default.result b/mysql-test/main/default.result index bd5ffba0d46..55b448229b5 100644 --- a/mysql-test/main/default.result +++ b/mysql-test/main/default.result @@ -3412,6 +3412,7 @@ INSERT INTO t1 VALUES (),(); SELECT 1 FROM t1 GROUP BY DEFAULT(pk); 1 1 +1 DROP TABLE t1; # # MDEV-28402: ASAN heap-use-after-free in create_tmp_table, @@ -3452,3 +3453,15 @@ drop table t1; # # End of 10.3 test # +# +# MDEV-26423: MariaDB server crash in Create_tmp_table::finalize +# +CREATE TABLE t1 (pk text DEFAULT length(uuid())); +INSERT INTO t1 VALUES (),(); +SELECT 1 FROM t1 GROUP BY DEFAULT(pk); +1 +1 +DROP TABLE t1; +# +# End of 10.4 test +# diff --git a/mysql-test/main/default.test b/mysql-test/main/default.test index a88817230e3..3064209a4a2 100644 --- a/mysql-test/main/default.test +++ b/mysql-test/main/default.test @@ -2160,3 +2160,15 @@ drop table t1; --echo # --echo # End of 10.3 test --echo # + +--echo # +--echo # MDEV-26423: MariaDB server crash in Create_tmp_table::finalize +--echo # +CREATE TABLE t1 (pk text DEFAULT length(uuid())); +INSERT INTO t1 VALUES (),(); +SELECT 1 FROM t1 GROUP BY DEFAULT(pk); +DROP TABLE t1; + +--echo # +--echo # End of 10.4 test +--echo # diff --git a/sql/item.cc b/sql/item.cc index a791d5bf8ca..f3eb7bcd741 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -9525,6 +9525,12 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) return Item_field::save_in_field(field_arg, no_conversions); } +void Item_default_value::save_in_result_field(bool no_conversions) +{ + calculate(); + Item_field::save_in_result_field(no_conversions); +} + double Item_default_value::val_result() { calculate(); @@ -9584,6 +9590,23 @@ table_map Item_default_value::used_tables() const return field->default_value->expr->used_tables(); } +bool Item_default_value::register_field_in_read_map(void *arg) +{ + TABLE *table= (TABLE *) arg; + int res= 0; + if (!table || (table && table == field->table)) + { + if (field->default_value && field->default_value->expr) + res= field->default_value->expr->walk(&Item::register_field_in_read_map,1,arg); + } + else if (result_field && table == result_field->table) + { + bitmap_set_bit(table->read_set, result_field->field_index); + } + + return res; +} + /** This method like the walk method traverses the item tree, but at the same time it can replace some nodes in the tree. diff --git a/sql/item.h b/sql/item.h index f074ea1e3da..52febaa3031 100644 --- a/sql/item.h +++ b/sql/item.h @@ -6490,6 +6490,7 @@ public: bool send(Protocol *protocol, st_value *buffer); int save_in_field(Field *field_arg, bool no_conversions); + void save_in_result_field(bool no_conversions); bool save_in_param(THD *thd, Item_param *param) { // It should not be possible to have "EXECUTE .. USING DEFAULT(a)" @@ -6509,6 +6510,7 @@ public: bool update_vcol_processor(void *arg) { return 0; } bool check_field_expression_processor(void *arg); bool check_func_default_processor(void *arg) { return true; } + bool register_field_in_read_map(void *arg); bool walk(Item_processor processor, bool walk_subquery, void *args) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1b8147a6cfb..534d75b20d7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -18094,7 +18094,10 @@ Field *Item_default_value::create_tmp_field_ex(TABLE *table, as the we have to calculate the default value before we can use it. */ get_tmp_field_src(src, param); - return tmp_table_field_from_field_type(table); + Field *result= tmp_table_field_from_field_type(table); + if (result && param->modify_item()) + result_field= result; + return result; } /* Same code as in Item_field::create_tmp_field_ex, except no default field