mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
Fixed bug mdev-10773.
The temporary tables created for recursive table references should be closed in close_thread_tables(), because they might be used in the statements like ANALYZE WITH r AS (...) SELECT * from r where r is defined through recursion.
This commit is contained in:
@ -2343,3 +2343,68 @@ select id + 1, uuid() from data_generator where id < 150000
|
|||||||
select * from data_generator
|
select * from data_generator
|
||||||
) as a;
|
) as a;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-10773: ANALYZE for query with recursive CTE
|
||||||
|
#
|
||||||
|
analyze format=json
|
||||||
|
with recursive src(counter) as
|
||||||
|
(select 1
|
||||||
|
union
|
||||||
|
select counter+1 from src where counter<10
|
||||||
|
) select * from src;
|
||||||
|
ANALYZE
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 1,
|
||||||
|
"r_loops": 1,
|
||||||
|
"r_total_time_ms": "REPLACED",
|
||||||
|
"table": {
|
||||||
|
"table_name": "<derived2>",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"r_loops": 1,
|
||||||
|
"rows": 2,
|
||||||
|
"r_rows": 10,
|
||||||
|
"r_total_time_ms": "REPLACED",
|
||||||
|
"filtered": 100,
|
||||||
|
"r_filtered": 100,
|
||||||
|
"materialized": {
|
||||||
|
"query_block": {
|
||||||
|
"recursive_union": {
|
||||||
|
"table_name": "<union2,3>",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"r_loops": 0,
|
||||||
|
"r_rows": null,
|
||||||
|
"query_specifications": [
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 2,
|
||||||
|
"table": {
|
||||||
|
"message": "No tables used"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"query_block": {
|
||||||
|
"select_id": 3,
|
||||||
|
"r_loops": 10,
|
||||||
|
"r_total_time_ms": "REPLACED",
|
||||||
|
"table": {
|
||||||
|
"table_name": "<derived2>",
|
||||||
|
"access_type": "ALL",
|
||||||
|
"r_loops": 10,
|
||||||
|
"rows": 2,
|
||||||
|
"r_rows": 1,
|
||||||
|
"r_total_time_ms": "REPLACED",
|
||||||
|
"filtered": 100,
|
||||||
|
"r_filtered": 90,
|
||||||
|
"attached_condition": "src.counter < 10"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1505,3 +1505,15 @@ select id, test_data
|
|||||||
) as a;
|
) as a;
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-10773: ANALYZE for query with recursive CTE
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--replace_regex /"r_total_time_ms": [0-9]*[.]?[0-9]*/"r_total_time_ms": "REPLACED"/
|
||||||
|
analyze format=json
|
||||||
|
with recursive src(counter) as
|
||||||
|
(select 1
|
||||||
|
union
|
||||||
|
select counter+1 from src where counter<10
|
||||||
|
) select * from src;
|
||||||
|
@ -769,6 +769,23 @@ void close_thread_tables(THD *thd)
|
|||||||
thd->derived_tables= 0;
|
thd->derived_tables= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (thd->rec_tables)
|
||||||
|
{
|
||||||
|
TABLE *next;
|
||||||
|
/*
|
||||||
|
Close all temporary tables created for recursive table references.
|
||||||
|
This action was postponed because the table could be used in the
|
||||||
|
statements like ANALYZE WITH r AS (...) SELECT * from r
|
||||||
|
where r is defined through recursion.
|
||||||
|
*/
|
||||||
|
for (table= thd->rec_tables ; table ; table= next)
|
||||||
|
{
|
||||||
|
next= table->next;
|
||||||
|
free_tmp_table(thd, table);
|
||||||
|
}
|
||||||
|
thd->rec_tables= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Mark all temporary tables used by this statement as free for reuse.
|
Mark all temporary tables used by this statement as free for reuse.
|
||||||
*/
|
*/
|
||||||
|
@ -1381,6 +1381,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
TABLE *derived_tables;
|
TABLE *derived_tables;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Temporary tables created for recursive table references.
|
||||||
|
*/
|
||||||
|
TABLE *rec_tables;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
During a MySQL session, one can lock tables in two modes: automatic
|
During a MySQL session, one can lock tables in two modes: automatic
|
||||||
or manual. In automatic mode all necessary tables are locked just before
|
or manual. In automatic mode all necessary tables are locked just before
|
||||||
@ -1461,6 +1466,7 @@ public:
|
|||||||
open_tables= 0;
|
open_tables= 0;
|
||||||
temporary_tables= 0;
|
temporary_tables= 0;
|
||||||
derived_tables= 0;
|
derived_tables= 0;
|
||||||
|
rec_tables= 0;
|
||||||
extra_lock= 0;
|
extra_lock= 0;
|
||||||
lock= 0;
|
lock= 0;
|
||||||
locked_tables_mode= LTM_NONE;
|
locked_tables_mode= LTM_NONE;
|
||||||
|
@ -283,7 +283,14 @@ void select_union_recursive::cleanup()
|
|||||||
tab->file->extra(HA_EXTRA_RESET_STATE);
|
tab->file->extra(HA_EXTRA_RESET_STATE);
|
||||||
tab->file->ha_delete_all_rows();
|
tab->file->ha_delete_all_rows();
|
||||||
}
|
}
|
||||||
free_tmp_table(thd, tab);
|
/*
|
||||||
|
The table will be closed later in close_thread_tables(),
|
||||||
|
because it might be used in the statements like
|
||||||
|
ANALYZE WITH r AS (...) SELECT * from r
|
||||||
|
where r is defined through recursion.
|
||||||
|
*/
|
||||||
|
tab->next= thd->rec_tables;
|
||||||
|
thd->rec_tables= tab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user