summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/derived_view.result53
-rw-r--r--mysql-test/t/derived_view.test24
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/table.cc3
4 files changed, 84 insertions, 1 deletions
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 3151bb14657..ef8e0a2a9cb 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -2034,6 +2034,59 @@ a
drop table t1,t2;
set optimizer_switch=@save968720_optimizer_switch;
#
+# LP BUG#978847 Server crashes in Item_ref::real_item on
+# INSERT .. SELECT with FROM subquery and derived_merge=ON
+SET @save978847_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+CREATE TABLE t1 ( a INT, b INT );
+INSERT INTO t1 VALUES (2,1),(3,2);
+select * from t1;
+a b
+2 1
+3 2
+INSERT INTO t1 SELECT * FROM
+( SELECT * FROM t1 ) AS alias;
+select * from t1;
+a b
+2 1
+3 2
+2 1
+3 2
+prepare stmt1 from 'INSERT INTO t1 SELECT SQL_BIG_RESULT * FROM
+ ( SELECT * FROM t1 ) AS alias';
+execute stmt1;
+select * from t1;
+a b
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+execute stmt1;
+select * from t1;
+a b
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+2 1
+3 2
+drop table t1;
+set optimizer_switch=@save978847_optimizer_switch;
+#
# end of 5.3 tests
#
set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index 03d308b6c45..3320ca25136 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -1414,6 +1414,30 @@ drop table t1,t2;
set optimizer_switch=@save968720_optimizer_switch;
--echo #
+--echo # LP BUG#978847 Server crashes in Item_ref::real_item on
+--echo # INSERT .. SELECT with FROM subquery and derived_merge=ON
+SET @save978847_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+
+CREATE TABLE t1 ( a INT, b INT );
+INSERT INTO t1 VALUES (2,1),(3,2);
+
+select * from t1;
+INSERT INTO t1 SELECT * FROM
+ ( SELECT * FROM t1 ) AS alias;
+select * from t1;
+prepare stmt1 from 'INSERT INTO t1 SELECT SQL_BIG_RESULT * FROM
+ ( SELECT * FROM t1 ) AS alias';
+execute stmt1;
+select * from t1;
+execute stmt1;
+select * from t1;
+
+drop table t1;
+
+set optimizer_switch=@save978847_optimizer_switch;
+
+--echo #
--echo # end of 5.3 tests
--echo #
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 3a5b6ac635f..38e56a49767 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8326,6 +8326,11 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
}
}
#endif
+ /*
+ field_iterator.create_item() builds used_items which we
+ have to save because changes made once and they are persistent
+ */
+ tables->persistent_used_items= tables->used_items;
if ((field= field_iterator.field()))
{
diff --git a/sql/table.cc b/sql/table.cc
index 8e420c715d5..ff104103374 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6088,7 +6088,8 @@ bool TABLE_LIST::change_refs_to_fields()
We need to restore the pointers after the execution of the
prepared statement.
*/
- thd->change_item_tree((Item **)&ref->ref, (Item*)materialized_items + idx);
+ thd->change_item_tree((Item **)&ref->ref,
+ (Item*)(materialized_items + idx));
}
return FALSE;