From 36888cc5318d66ff871294a81ff2746d2f889dd4 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 21 Dec 2017 10:23:56 +0300 Subject: [PATCH] MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [fixes #422] --- .../suite/versioning/r/select_sp.result | 15 +++++- mysql-test/suite/versioning/t/select_sp.test | 13 ++++- sql/sql_lex.cc | 2 - sql/sql_lex.h | 2 - sql/sql_select.cc | 52 ++++--------------- sql/table.h | 1 - 6 files changed, 34 insertions(+), 51 deletions(-) diff --git a/mysql-test/suite/versioning/r/select_sp.result b/mysql-test/suite/versioning/r/select_sp.result index 35ae4256418..a8452add78a 100644 --- a/mysql-test/suite/versioning/r/select_sp.result +++ b/mysql-test/suite/versioning/r/select_sp.result @@ -207,7 +207,20 @@ RJ2_x1 y1 x2 y2 1 3 1 2 NULL NULL 2 1 NULL NULL 3 1 -create table t1( +# MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [#422] +create or replace table t1 (called int, bad int) with system versioning; +create or replace procedure bad() select * from t1 where bad in (select called from t1); +called bad +called bad +called bad +called bad +called bad +called bad +called bad +called bad +bad() is good. +# wildcard expansion on hidden fields. +create or replace table t1( A int ) with system versioning; insert into t1 values(1); diff --git a/mysql-test/suite/versioning/t/select_sp.test b/mysql-test/suite/versioning/t/select_sp.test index 7551d5e2efb..c0ca7589463 100644 --- a/mysql-test/suite/versioning/t/select_sp.test +++ b/mysql-test/suite/versioning/t/select_sp.test @@ -106,8 +106,17 @@ delimiter ;~~ call test_01(); call test_02(); -# wildcard expansion on hidden fields. -create table t1( +--echo # MDEV-14686 Server crashes in Item_field::used_tables on 2nd call of SP [#422] +create or replace table t1 (called int, bad int) with system versioning; +create or replace procedure bad() select * from t1 where bad in (select called from t1); +--disable_query_log +call bad; call bad; call bad; call bad; call bad; call bad; call bad; call bad; +drop procedure bad; +--enable_query_log +--echo bad() is good. + +--echo # wildcard expansion on hidden fields. +create or replace table t1( A int ) with system versioning; insert into t1 values(1); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 252d97d0fad..7384831d5e3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2270,7 +2270,6 @@ void st_select_lex::init_query() window_funcs.empty(); tvc= 0; in_tvc= false; - vers_saved_where= NULL; versioned_tables= 0; } @@ -2313,7 +2312,6 @@ void st_select_lex::init_select() in_funcs.empty(); curr_tvc_name= 0; in_tvc= false; - vers_saved_where= NULL; versioned_tables= 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index c00ca301384..221d3d76f69 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1045,8 +1045,6 @@ public: bool in_tvc; /** System Versioning */ -private: - Item *vers_saved_where; public: uint versioned_tables; int vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1bd0f2ab922..b65131fb9c9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -62,6 +62,8 @@ #include #include #include "sys_vars_shared.h" +#include "sp_head.h" +#include "sp_rcontext.h" /* A key part number that means we're using a fulltext scan. @@ -754,49 +756,6 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr because they must outlive execution phase for multiple executions. */ Query_arena_stmt on_stmt_arena(thd); - if (vers_saved_where) - { - DBUG_ASSERT(thd->stmt_arena->is_sp_execute()); - /* 2. this copy_andor_structure() is also required by the same reason */ - *where_expr= vers_saved_where->copy_andor_structure(thd); - } - else if (thd->stmt_arena->is_sp_execute()) - { - if (thd->stmt_arena->is_stmt_execute()) // SP executed second time (STMT_EXECUTED) - *where_expr= 0; - else if (*where_expr) // SP executed first time (STMT_INITIALIZED_FOR_SP) - /* 1. copy_andor_structure() is required since this andor tree - is modified later (and on shorter arena) */ - vers_saved_where= (*where_expr)->copy_andor_structure(thd); - } - - /* We have to save also non-versioned on_expr since we may have - conjuction of versioned + non-versioned */ - if (thd->stmt_arena->is_sp_execute()) - { - for (table= tables; table; table= table->next_local) - { - if (!table->table) - continue; - - if (table->saved_on_expr) // same logic as vers_saved_where - { - if (table->on_expr) - table->on_expr= table->saved_on_expr->copy_andor_structure(thd); - else - // on_expr was moved to WHERE (see below: Add ON expression to the WHERE) - *where_expr= and_items(thd, - *where_expr, - table->saved_on_expr->copy_andor_structure(thd)); - } - else if (table->on_expr && - thd->stmt_arena->state == Query_arena::STMT_INITIALIZED_FOR_SP) - { - table->saved_on_expr= table->on_expr->copy_andor_structure(thd); - } - } - } - // find outer system_time SELECT_LEX *outer_slex= outer_select(); TABLE_LIST* outer_table= NULL; @@ -1103,6 +1062,13 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables, COND **where_expr if (outer_table) outer_table->vers_conditions.type= SYSTEM_TIME_ALL; + + // Invalidate current SP [#52, #422] + if (thd->spcont) + { + DBUG_ASSERT(thd->spcont->m_sp); + thd->spcont->m_sp->set_sp_cache_version(ULONG_MAX); + } } DBUG_RETURN(0); diff --git a/sql/table.h b/sql/table.h index 2437901b92d..1b6bc20b40e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1958,7 +1958,6 @@ struct TABLE_LIST const char *db, *alias, *table_name, *schema_table_name; const char *option; /* Used by cache index */ Item *on_expr; /* Used with outer join */ - Item *saved_on_expr; /* Used with SP and System Versioning */ Item *sj_on_expr; /*