1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Fixed bug mdev-11674.

1. The rows of a recursive CTE at some point may overflow
the HEAP temporary table containing them. At this point
the table is converted to a MyISAM temporary table and the
new added rows are placed into this MyISAM table.
A bug in the of select_union_recursive::send_data prevented
the server from writing the row that caused the overflow
into the temporary table used for the result of the iteration
steps. This could lead, in particular,to a premature end
of the iterations.
2. The method TABLE::insert_all_rows_into() that was used
to copy all rows of one temporary table into another
did not take into account that the destination temporary
table must be converted to a MyISAM table at some point.
This patch fixed this problem. It also renamed the method
into TABLE::insert_all_rows_into_tmp_table() and added
an extra parameter needed for the conversion.
This commit is contained in:
Igor Babaev
2017-01-04 14:33:24 -08:00
parent a758479c10
commit 348ccb6f03
6 changed files with 74 additions and 15 deletions

View File

@ -105,7 +105,7 @@ int select_union_recursive::send_data(List<Item> &values)
{
int rc= select_union::send_data(values);
if (!write_err)
if (write_err != HA_ERR_FOUND_DUPP_KEY)
{
int err;
if ((err= incr_table->file->ha_write_tmp_row(table->record[0])))
@ -1192,6 +1192,7 @@ bool st_select_lex_unit::exec_recursive()
st_select_lex *end= NULL;
bool is_unrestricted= with_element->is_unrestricted();
List_iterator_fast<TABLE> li(with_element->rec_result->rec_tables);
TMP_TABLE_PARAM *tmp_table_param= &with_element->rec_result->tmp_table_param;
ha_rows examined_rows= 0;
bool was_executed= executed;
TABLE *rec_table;
@ -1247,7 +1248,9 @@ bool st_select_lex_unit::exec_recursive()
while ((rec_table= li++))
{
saved_error=
incr_table->insert_all_rows_into(thd, rec_table, !is_unrestricted);
incr_table->insert_all_rows_into_tmp_table(thd, rec_table,
tmp_table_param,
!is_unrestricted);
if (!with_element->rec_result->first_rec_table_to_update)
with_element->rec_result->first_rec_table_to_update= rec_table;
if (with_element->level == 1)