diff options
author | Igor Babaev <igor@askmonty.org> | 2017-01-28 14:52:19 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2017-01-28 15:47:11 -0800 |
commit | abfcdb8fbc4dec1ef9e6ea8fc9961344186b0209 (patch) | |
tree | ad29f96d2bbff77ef346507d387f6b31b907a6f8 | |
parent | 64b5e94236e7c4246863fc70b91c346ba7b66b8b (diff) | |
download | mariadb-git-abfcdb8fbc4dec1ef9e6ea8fc9961344186b0209.tar.gz |
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.
-rw-r--r-- | mysql-test/r/cte_recursive.result | 65 | ||||
-rw-r--r-- | mysql-test/t/cte_recursive.test | 12 | ||||
-rw-r--r-- | sql/sql_base.cc | 17 | ||||
-rw-r--r-- | sql/sql_class.h | 6 | ||||
-rw-r--r-- | sql/sql_union.cc | 9 |
5 files changed, 108 insertions, 1 deletions
diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index d5476aec1c4..20ca5c8f8cb 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -2343,3 +2343,68 @@ select id + 1, uuid() from data_generator where id < 150000 select * from data_generator ) as a; 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" + } + } + } + ] + } + } + } + } + } +} diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test index ea0f73be259..332996d4921 100644 --- a/mysql-test/t/cte_recursive.test +++ b/mysql-test/t/cte_recursive.test @@ -1505,3 +1505,15 @@ select id, test_data ) as a; 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; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ac4b8a45107..3758b3ba710 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -769,6 +769,23 @@ void close_thread_tables(THD *thd) 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. */ diff --git a/sql/sql_class.h b/sql/sql_class.h index b6dafd939bc..295474d0d62 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1381,6 +1381,11 @@ public: */ 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 or manual. In automatic mode all necessary tables are locked just before @@ -1461,6 +1466,7 @@ public: open_tables= 0; temporary_tables= 0; derived_tables= 0; + rec_tables= 0; extra_lock= 0; lock= 0; locked_tables_mode= LTM_NONE; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index b30b5528741..71d0e331101 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -283,7 +283,14 @@ void select_union_recursive::cleanup() tab->file->extra(HA_EXTRA_RESET_STATE); 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; } } |