1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

MDEV-23406 Signal 8 in maria_create after recursive cte query

This bug could cause a crash when executing queries that used mutually
recursive CTEs with system variable big_tables set to 1. It happened due
to several bugs in the code that handled recursive table references
referred mutually recursive CTEs. For each recursive table reference a
temporary table is created that contains all rows generated for the
corresponding recursive CTE table on the previous step of recursion.
This temporary table should be created in the same way as the temporary
table created for a regular materialized derived table using the
method select_union::create_result_table(). In this case when the
temporary table is created it uses the select_union::TMP_TABLE_PARAM
structure as the parameter for the table construction. However the
code created the temporary table using just the function create_tmp_table()
and passed pointers to certain fields of the TMP_TABLE_PARAM structure
used for accumulation of rows of the recursive CTE table as parameters
for update. This was a mistake because now different temporary tables
cannot share some TMP_TABLE_PARAM fields in a general case. Besides,
depending on how mutually recursive CTE tables were defined and which
of them were referred in the executed query the select_union object
allocated for a recursive table reference could be allocated again after
the the temporary table had been created. In this case the TMP_TABLE_PARAM
object associated with the temporary table created for the recursive
table reference contained unassigned fields needed for execution when
Aria engine is employed as the engine for temporary tables.
This patch ensures that
- select_union object is created only once for any recursive table
  reference
- any temporary table created for recursive CTEs uses its own
  TMP_TABLE_PARAM structure
The patch also fixes a problem caused by incomplete cleanup of join tables
associated with recursive table references.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
Igor Babaev
2020-12-16 09:11:11 -08:00
parent 719da2c4cc
commit a244be7044
7 changed files with 370 additions and 39 deletions

View File

@ -5152,10 +5152,15 @@ class select_union_recursive :public select_union
public:
/* The temporary table with the new records generated by one iterative step */
TABLE *incr_table;
/* The TMP_TABLE_PARAM structure used to create incr_table */
TMP_TABLE_PARAM incr_table_param;
/* One of tables from the list rec_tables (determined dynamically) */
TABLE *first_rec_table_to_update;
/* The temporary tables used for recursive table references */
List<TABLE> rec_tables;
/*
The list of all recursive table references to the CTE for whose
specification this select_union_recursive was created
*/
List<TABLE_LIST> rec_table_refs;
/*
The count of how many times cleanup() was called with cleaned==false
for the unit specifying the recursive CTE for which this object was created
@ -5165,7 +5170,8 @@ class select_union_recursive :public select_union
select_union_recursive(THD *thd_arg):
select_union(thd_arg),
incr_table(0), first_rec_table_to_update(0), cleanup_count(0) {};
incr_table(0), first_rec_table_to_update(0), cleanup_count(0)
{ incr_table_param.init(); };
int send_data(List<Item> &items);
bool create_result_table(THD *thd, List<Item> *column_types,