From 560ff1a2ea1e2f438b27a12b65b5f2361e1d6231 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Jul 2005 05:31:16 +0400 Subject: [PATCH] Fix bug#11868 NOT NULL ref optimization in subquery used in update must be disabled if ref is built with a key from the updated table Problem was in add_not_null_conds() optimization function. It contains following code: JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; ... add_cond_and_fix(&referred_tab->select_cond, notnull); For UPDATE described in bug report referred_tab is 0 and dereferencing it crashes the server. sql/sql_select.cc: Fix bug #11868 NOT NULL ref optimization in subquery used in update must be disabled if ref is built with a key from the updated table mysql-test/r/update.result: Test case for bug#11868 Update with subquery with ref built with a key from the updated table crashes server. mysql-test/t/update.test: Test case for bug#11868 Update with subquery with ref built with a key from the updated table crashes server --- mysql-test/r/update.result | 11 +++++++++++ mysql-test/t/update.test | 13 +++++++++++++ sql/sql_select.cc | 7 ++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/update.result b/mysql-test/r/update.result index d83952e118b..e35d4e29fe4 100644 --- a/mysql-test/r/update.result +++ b/mysql-test/r/update.result @@ -240,3 +240,14 @@ update t1, t2 set t1.a = t2.a where t2.b = t1.b; show warnings; Level Code Message drop table t1, t2; +create table t1(f1 int, f2 int); +create table t2(f3 int, f4 int); +create index idx on t2(f3); +insert into t1 values(1,0),(2,0); +insert into t2 values(1,1),(2,2); +UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); +select * from t1; +f1 f2 +1 1 +2 2 +drop table t1,t2; diff --git a/mysql-test/t/update.test b/mysql-test/t/update.test index 6a90fb95760..41f7d37e6d0 100644 --- a/mysql-test/t/update.test +++ b/mysql-test/t/update.test @@ -201,3 +201,16 @@ analyze table t1,t2; update t1, t2 set t1.a = t2.a where t2.b = t1.b; show warnings; drop table t1, t2; + +# +# Bug #11868 Update with subquery with ref built with a key from the updated +# table crashes server +# +create table t1(f1 int, f2 int); +create table t2(f3 int, f4 int); +create index idx on t2(f3); +insert into t1 values(1,0),(2,0); +insert into t2 values(1,1),(2,2); +UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); +select * from t1; +drop table t1,t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 43cf649685e..e56828c3244 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3555,7 +3555,12 @@ static void add_not_null_conds(JOIN *join) DBUG_ASSERT(item->type() == Item::FIELD_ITEM); Item_field *not_null_item= (Item_field*)item; JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; - if (referred_tab->join != join) + /* + For UPDATE queries such as: + UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); + not_null_item is the t1.f1, but it's referred_tab is 0. + */ + if (!referred_tab || referred_tab->join != join) continue; Item *notnull; if (!(notnull= new Item_func_isnotnull(not_null_item)))