From f053349797a1dca5206a3b8d5ff33353f45430d8 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 16 Jul 2021 22:46:50 -0700 Subject: MDEV-26135 Assertion failure when executing PS with a hanging recursive CTE The bug affected execution of queries with With clauses containing so-called hanging recursive CTEs in PREPARE mode. A CTE is hanging if it's not used in the query. Preparation of a prepared statement from a query with a hanging CTE caused a leak in the server and execution of this prepared statement led to an assert failure of the server built in the debug mode. This happened because the units specifying recursive CTEs erroneously were not cleaned up if those CTEs were hanging. The patch enforces cleanup of hanging recursive CTEs in the same way as other hanging CTEs. Approved by dmitry.shulga@mariadb.com --- sql/sql_union.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sql/sql_union.cc') diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 7baedfb259c..e5648e6989b 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1382,7 +1382,8 @@ bool st_select_lex_unit::cleanup() { DBUG_RETURN(FALSE); } - if (with_element && with_element->is_recursive && union_result) + if (with_element && with_element->is_recursive && union_result && + with_element->rec_outer_references) { select_union_recursive *result= with_element->rec_result; if (++result->cleanup_count == with_element->rec_outer_references) @@ -1584,7 +1585,8 @@ bool st_select_lex::cleanup() for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ; lex_unit= lex_unit->next_unit()) { - if (lex_unit->with_element && lex_unit->with_element->is_recursive) + if (lex_unit->with_element && lex_unit->with_element->is_recursive && + lex_unit->with_element->rec_outer_references) continue; error= (bool) ((uint) error | (uint) lex_unit->cleanup()); } -- cgit v1.2.1 From 4c387945f0f8d5df84ae987c4a4bba7675815c72 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 9 Jul 2021 18:56:34 -0700 Subject: MDEV-25565 Crash on 2-nd execution of SP/PS for query calculating window functions from view A crash of the server happened when executing a stored procedure whose the only query calculated window functions over a mergeable view specified as a select from non-mergeable view. The crash could be reproduced if the window specifications of the window functions were identical and both contained PARTITION lists and ORDER BY lists. A crash also happened on the second execution of the prepared statement created for such query. If to use derived tables or CTE instead of views the problem still manifests itself crashing the server. When optimizing the window specifications of a window function the server can substitute the partition lists and the order lists for the corresponding lists from another window specification in the case when the lists are identical. This substitution is not permanent and should be rolled back before the second execution. It was not done and this ultimately led to a crash when resolving the column names at the second execution of SP/PS. --- sql/sql_union.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'sql/sql_union.cc') diff --git a/sql/sql_union.cc b/sql/sql_union.cc index e5648e6989b..8f7aca2a8ed 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -30,6 +30,7 @@ #include "filesort.h" // filesort_free_buffers #include "sql_view.h" #include "sql_cte.h" +#include "item_windowfunc.h" bool mysql_union(THD *thd, LEX *lex, select_result *result, SELECT_LEX_UNIT *unit, ulong setup_tables_done_option) @@ -1551,6 +1552,29 @@ static void cleanup_order(ORDER *order) } +static void cleanup_window_funcs(List &win_funcs) +{ + List_iterator_fast it(win_funcs); + Item_window_func *win_func; + while ((win_func= it++)) + { + Window_spec *win_spec= win_func->window_spec; + if (!win_spec) + continue; + if (win_spec->save_partition_list) + { + win_spec->partition_list= win_spec->save_partition_list; + win_spec->save_partition_list= NULL; + } + if (win_spec->save_order_list) + { + win_spec->order_list= win_spec->save_order_list; + win_spec->save_order_list= NULL; + } + } +} + + bool st_select_lex::cleanup() { bool error= FALSE; @@ -1559,6 +1583,8 @@ bool st_select_lex::cleanup() cleanup_order(order_list.first); cleanup_order(group_list.first); + cleanup_window_funcs(window_funcs); + if (join) { List_iterator ti(leaf_tables); -- cgit v1.2.1 From c86f813afe372a9dffc1badbc8f26e35e9d44b29 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 23 Apr 2019 13:45:28 +0400 Subject: MDEV-9234 Add Type_handler::union_element_finalize() --- sql/sql_union.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sql/sql_union.cc') diff --git a/sql/sql_union.cc b/sql/sql_union.cc index a4ad67ae74e..c89e59a06f8 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1150,12 +1150,12 @@ cont: while ((type= tp++)) { - if (type->cmp_type() == STRING_RESULT && - type->collation.derivation == DERIVATION_NONE) - { - my_error(ER_CANT_AGGREGATE_NCOLLATIONS, MYF(0), "UNION"); + /* + Test if the aggregated data type is OK for a UNION element. + E.g. in case of string data, DERIVATION_NONE is not allowed. + */ + if (type->type_handler()->union_element_finalize(type)) goto err; - } } /* -- cgit v1.2.1 From 6152ab7b42c18d62030ef9c23e9abb3817c73f39 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 27 Jul 2021 23:45:30 +0200 Subject: MDEV-24511 null field is created with CREATE..SELECT When creating fields for UNION results, Field_null is not allowed. Should create binary(0) instead. --- sql/sql_union.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_union.cc') diff --git a/sql/sql_union.cc b/sql/sql_union.cc index c89e59a06f8..48d8c16db68 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1154,7 +1154,8 @@ cont: Test if the aggregated data type is OK for a UNION element. E.g. in case of string data, DERIVATION_NONE is not allowed. */ - if (type->type_handler()->union_element_finalize(type)) + if (type->type() == Item::TYPE_HOLDER && type->type_handler()-> + union_element_finalize(static_cast(type))) goto err; } -- cgit v1.2.1