diff --git a/mysql-test/main/query_cache.result b/mysql-test/main/query_cache.result index fc7ca726c48..a98ab3cab76 100644 --- a/mysql-test/main/query_cache.result +++ b/mysql-test/main/query_cache.result @@ -2207,6 +2207,33 @@ Variable_name Value Qcache_queries_in_cache 0 DROP FUNCTION foo; drop table t1; +# +# MDEV-33861: main.query_cache fails with embedded after +# enabling WITH_PROTECT_STATEMENT_MEMROOT +# +create table t1 (s1 int); +create procedure f3 () begin +select * from t1; +end; +// +create procedure f4 () begin +select * from t1; +end; +// +Call f4(); +s1 +cAll f3(); +s1 +insert into t1 values (2); +caLl f3(); +s1 +2 +drop procedure f3; +drop procedure f4; +drop table t1; +# +# End of 10.4 tests +# restore defaults SET GLOBAL query_cache_type= default; SET GLOBAL query_cache_size=@save_query_cache_size; diff --git a/mysql-test/main/query_cache.test b/mysql-test/main/query_cache.test index f4913c99d1c..5d523764dce 100644 --- a/mysql-test/main/query_cache.test +++ b/mysql-test/main/query_cache.test @@ -1803,6 +1803,41 @@ show status like "Qcache_queries_in_cache"; DROP FUNCTION foo; drop table t1; + +--echo # +--echo # MDEV-33861: main.query_cache fails with embedded after +--echo # enabling WITH_PROTECT_STATEMENT_MEMROOT +--echo # + +create table t1 (s1 int); +--delimiter // +create procedure f3 () begin +select * from t1; +end; +// +create procedure f4 () begin +select * from t1; +end; +// +--delimiter ; + +Call f4(); + +cAll f3(); + +insert into t1 values (2); + +caLl f3(); + +drop procedure f3; +drop procedure f4; +drop table t1; + + +--echo # +--echo # End of 10.4 tests +--echo # + --echo restore defaults SET GLOBAL query_cache_type= default; SET GLOBAL query_cache_size=@save_query_cache_size; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 312d779b05a..faf483c4a35 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3702,6 +3702,9 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) thd->update_stats(); thd->lex->sql_command= save_sql_command; *nextp= m_ip+1; +#ifdef PROTECT_STATEMENT_MEMROOT + mark_as_qc_used(); +#endif } thd->set_query(query_backup); thd->query_name_consts= 0; diff --git a/sql/sp_head.h b/sql/sp_head.h index 693a5e78703..c9b6ae63c2b 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -1100,7 +1100,7 @@ public: sp_instr(uint ip, sp_pcontext *ctx) :Query_arena(0, STMT_INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx) #ifdef PROTECT_STATEMENT_MEMROOT - , m_has_been_run(false) + , m_has_been_run(NON_RUN) #endif {} @@ -1194,21 +1194,29 @@ public: #ifdef PROTECT_STATEMENT_MEMROOT bool has_been_run() const { - return m_has_been_run; + return m_has_been_run == RUN; + } + + void mark_as_qc_used() + { + m_has_been_run= QC; } void mark_as_run() { - m_has_been_run= true; + if (m_has_been_run == QC) + m_has_been_run= NON_RUN; // answer was from WC => not really executed + else + m_has_been_run= RUN; } void mark_as_not_run() { - m_has_been_run= false; + m_has_been_run= NON_RUN; } private: - bool m_has_been_run; + enum {NON_RUN, QC, RUN} m_has_been_run; #endif }; // class sp_instr : public Sql_alloc