#At file:///home/gluh/MySQL/mysql-5.0-bug-47371/ based on revid:jperkin@stripped
2819 Sergey Glukhov 2009-10-13
Bug#47371 reference by same column name
At the end of execution top level join execution
we do full cleanup for this join.
It leads to underlying join full cleanup(subquery) too
as we don't take into account 'uncacheable' flag for
subquery joins. It may cause a crash in case when
we need to evaluate subquery later.
The fix is to perform full cleanup for underlying subquery joins
only if subquery is not uncacheable.
@ mysql-test/r/user_var.result
test result
@ mysql-test/t/user_var.test
test case
@ sql/mysql_priv.h
reverted fix for bug#37460 as unnecessary
@ sql/sql_select.cc
At the end of execution top level join execution
we do full cleanup for this join.
It leads to underlying join full cleanup(subquery) too
as we don't take into account 'uncacheable' flag for
subquery joins. It may cause a crash in case when
we need to evaluate subquery later.
The fix is to perform full cleanup for underlying subquery joins
only if subquery is not uncacheable.
@ sql/sql_update.cc
reverted fix for bug#37460 as unnecessary
modified:
mysql-test/r/user_var.result
mysql-test/t/user_var.test
sql/mysql_priv.h
sql/sql_select.cc
sql/sql_update.cc
=== modified file 'mysql-test/r/user_var.result'
--- a/mysql-test/r/user_var.result 2009-02-24 14:47:12 +0000
+++ b/mysql-test/r/user_var.result 2009-10-13 08:31:39 +0000
@@ -363,4 +363,19 @@ SELECT a, b FROM t1 WHERE a=2 AND b=3 GR
a b
2 3
DROP TABLE t1;
+CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL);
+CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11));
+CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL);
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t3 VALUES(10, 10);
+INSERT INTO t3 VALUES(10, 10);
+SELECT MIN(t2.f1),
+@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
+FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1;
+MIN(t2.f1) @bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
+10 NULL
+DROP TABLE t1, t2, t3;
End of 5.0 tests
=== modified file 'mysql-test/t/user_var.test'
--- a/mysql-test/t/user_var.test 2009-02-24 14:47:12 +0000
+++ b/mysql-test/t/user_var.test 2009-10-13 08:31:39 +0000
@@ -248,4 +248,24 @@ SELECT @a, @b;
SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b;
DROP TABLE t1;
+#
+# Bug#47371: reference by same column name
+#
+CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL);
+CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11));
+CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL);
+
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t1 VALUES(10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t2 VALUES(10, 10, 10);
+INSERT INTO t3 VALUES(10, 10);
+INSERT INTO t3 VALUES(10, 10);
+
+SELECT MIN(t2.f1),
+@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo)
+FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1;
+
+DROP TABLE t1, t2, t3;
+
--echo End of 5.0 tests
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2009-05-27 10:20:57 +0000
+++ b/sql/mysql_priv.h 2009-10-13 08:31:39 +0000
@@ -449,7 +449,6 @@ MY_LOCALE *my_locale_by_number(uint numb
#define UNCACHEABLE_PREPARE 16
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */
#define UNCACHEABLE_UNITED 32
-#define UNCACHEABLE_CHECKOPTION 64
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
#define UNDEF_POS (-1)
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2009-09-18 09:34:08 +0000
+++ b/sql/sql_select.cc 2009-10-13 08:31:39 +0000
@@ -6476,7 +6476,9 @@ void JOIN::join_free()
for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
{
Item_subselect *subselect= sl->master_unit()->item;
- bool full_local= full && (!subselect || subselect->is_evaluated());
+ bool full_local= full && (!subselect ||
+ subselect->is_evaluated() &&
+ !subselect->is_uncacheable());
/*
If this join is evaluated, we can fully clean it up and clean up all
its underlying joins even if they are correlated -- they will not be
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2009-08-28 15:51:31 +0000
+++ b/sql/sql_update.cc 2009-10-13 08:31:39 +0000
@@ -1255,32 +1255,6 @@ multi_update::initialize_tables(JOIN *jo
}
}
- /*
- enable uncacheable flag if we update a view with check option
- and check option has a subselect, otherwise, the check option
- can be evaluated after the subselect was freed as independent
- (See full_local in JOIN::join_free()).
- */
- if (table_ref->check_option && !join->select_lex->uncacheable)
- {
- SELECT_LEX_UNIT *tmp_unit;
- SELECT_LEX *sl;
- for (tmp_unit= join->select_lex->first_inner_unit();
- tmp_unit;
- tmp_unit= tmp_unit->next_unit())
- {
- for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
- {
- if (sl->master_unit()->item)
- {
- join->select_lex->uncacheable|= UNCACHEABLE_CHECKOPTION;
- goto loop_end;
- }
- }
- }
- }
-loop_end:
-
if (table == first_table_for_update && table_ref->check_option)
{
table_map unupdated_tables= table_ref->check_option->used_tables() &
Attachment: [text/bzr-bundle] bzr/sergey.glukhov@sun.com-20091013083139-t0umu3yydxp5qdyi.bundle