From a270e8abc4344654aaac1a6881cbb169165a3cf0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Jul 2014 10:11:10 +0300 Subject: [PATCH] MDEV-6441: memory leak mysql_derived_prepare() was executed on the statement memory. Now it is executed on the runtime memory. All bugs induced by this were fixed. --- mysql-test/r/view.result | 55 +++++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 63 ++++++++++++++++++++++++++++++++++++++++ sql/sql_derived.cc | 6 +--- sql/sql_lex.cc | 2 +- sql/table.cc | 3 +- 5 files changed, 122 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index de78de3282b..4511c4502ea 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5302,6 +5302,61 @@ NULL 8 drop view v1; drop table t1,t2,t3; SET optimizer_switch=@save_optimizer_switch_MDEV_3874; +CREATE TABLE `t1` ( +`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, +`f0` int(11) unsigned NOT NULL DEFAULT '0', +`f1` int(11) unsigned NOT NULL DEFAULT '0', +PRIMARY KEY (`id`), +UNIQUE KEY `id` (`id`) +); +CREATE TABLE `t2` ( +`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, +`f02` bigint(20) unsigned NOT NULL DEFAULT '0', +`f03` int(11) unsigned NOT NULL DEFAULT '0', +PRIMARY KEY (`id`), +UNIQUE KEY `id` (`id`) +); +CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `v1` AS +SELECT +`t1`.`f0` AS `f0`, +`t1`.`f1` AS `f1`, +`t2`.`f02` AS `f02`, +`t2`.`f03` AS `f03` +FROM +(`t1` LEFT JOIN `t2` ON((`t1`.`id` = `t2`.`f02`))); +CREATE FUNCTION `f1`( +p0 BIGINT(20) UNSIGNED +) +RETURNS bigint(20) unsigned +DETERMINISTIC +CONTAINS SQL +SQL SECURITY DEFINER +COMMENT '' +BEGIN +DECLARE k0 INTEGER UNSIGNED DEFAULT 0; +DECLARE lResult INTEGER UNSIGNED DEFAULT 0; +SET k0 = 0; +WHILE k0 < 1 DO +SELECT COUNT(*) as `f00` INTO lResult FROM `v1` WHERE `v1`.`f0` = p0; -- BUG +SET k0 = k0 + 1; +END WHILE; +RETURN(k0); +END| +SELECT `f1`(1); +`f1`(1) +1 +SELECT `f1`(1); +`f1`(1) +1 +SELECT `f1`(1); +`f1`(1) +1 +SELECT `f1`(1); +`f1`(1) +1 +DROP FUNCTION f1; +DROP VIEW v1; +DROP TABLE t1, t2; # ----------------------------------------------------------------- # -- End of 5.5 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 24577368c06..5f3e69431ee 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5231,6 +5231,69 @@ drop view v1; drop table t1,t2,t3; SET optimizer_switch=@save_optimizer_switch_MDEV_3874; +# +# MDEV-5515: sub-bug test of 3rd execution crash +# + +CREATE TABLE `t1` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `f0` int(11) unsigned NOT NULL DEFAULT '0', + `f1` int(11) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `id` (`id`) +); + +CREATE TABLE `t2` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `f02` bigint(20) unsigned NOT NULL DEFAULT '0', + `f03` int(11) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `id` (`id`) +); + +CREATE ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW `v1` AS + SELECT + `t1`.`f0` AS `f0`, + `t1`.`f1` AS `f1`, + `t2`.`f02` AS `f02`, + `t2`.`f03` AS `f03` + FROM + (`t1` LEFT JOIN `t2` ON((`t1`.`id` = `t2`.`f02`))); + +--delimiter | +CREATE FUNCTION `f1`( + p0 BIGINT(20) UNSIGNED + ) + RETURNS bigint(20) unsigned + DETERMINISTIC + CONTAINS SQL + SQL SECURITY DEFINER + COMMENT '' +BEGIN + +DECLARE k0 INTEGER UNSIGNED DEFAULT 0; +DECLARE lResult INTEGER UNSIGNED DEFAULT 0; + + SET k0 = 0; + WHILE k0 < 1 DO + SELECT COUNT(*) as `f00` INTO lResult FROM `v1` WHERE `v1`.`f0` = p0; -- BUG + SET k0 = k0 + 1; + END WHILE; + + RETURN(k0); +END| +--delimiter ; + + +SELECT `f1`(1); +SELECT `f1`(1); +SELECT `f1`(1); +SELECT `f1`(1); + +DROP FUNCTION f1; +DROP VIEW v1; +DROP TABLE t1, t2; + --echo # ----------------------------------------------------------------- --echo # -- End of 5.5 tests. --echo # ----------------------------------------------------------------- diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index be258c16356..004cccb41a9 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -614,6 +614,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) SELECT_LEX_UNIT *unit= derived->get_unit(); DBUG_ENTER("mysql_derived_prepare"); bool res= FALSE; + DBUG_PRINT("enter", ("unit 0x%lx", (ulong) unit)); // Skip already prepared views/DT if (!unit || unit->prepared || @@ -623,9 +624,6 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) thd->lex->sql_command == SQLCOM_DELETE_MULTI)))) DBUG_RETURN(FALSE); - Query_arena *arena, backup; - arena= thd->activate_stmt_arena_if_needed(&backup); - SELECT_LEX *first_select= unit->first_select(); /* prevent name resolving out of derived table */ @@ -743,8 +741,6 @@ exit: if (derived->outer_join) table->maybe_null= 1; } - if (arena) - thd->restore_active_arena(arena, &backup); DBUG_RETURN(res); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 8dab2191224..b9f84ac542d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3298,7 +3298,7 @@ static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl) { for (; tbl; tbl= tbl->next_local) { - if (tbl->on_expr) + if (tbl->on_expr && !tbl->prep_on_expr) { thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr); tbl->on_expr= tbl->on_expr->copy_andor_structure(thd); diff --git a/sql/table.cc b/sql/table.cc index c431f8dcc02..aa63f79c9bd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4140,7 +4140,8 @@ bool TABLE_LIST::create_field_translation(THD *thd) while ((item= it++)) { - transl[field_count].name= item->name; + DBUG_ASSERT(item->name && item->name[0]); + transl[field_count].name= thd->strdup(item->name); transl[field_count++].item= item; } field_translation= transl;