3232 Guilhem Bichot 2010-08-26
Fix for BUG#56254 "Assertion tab->ref.use_count fails in join_read_key_unlock_row() on 4-way JOIN"
now that evaluate_null_complemented_join_record() cascades into evaluate_join_record()
(after fix for BUG 54437), this started unlocking a NULL-complemented (thus non-locked) row...
@ mysql-test/t/join_outer.test
test for bug, used to assert in join_read_key_unlock_row()
@ sql/sql_select.cc
don't unlock NULL-complemented rows, they are not in table, they are not locked.
For the test to be reliable, not_null_compl needs to be properly set: we
set it to true at start of sub_select(), before we read rows from the table;
if we find no matching row, sub_select() calls
evaluate_null_complemented_join_record() which sets it to false. Next time we
read the table in the nested loop join, sub_select() sets it to true again.
modified:
mysql-test/r/join_outer.result
mysql-test/r/join_outer_jcl6.result
mysql-test/t/join_outer.test
sql/sql_select.cc
3231 Evgeny Potemkin 2010-08-24
Post-merge fix.
modified:
mysql-test/r/locale.result
=== modified file 'mysql-test/r/join_outer.result'
--- a/mysql-test/r/join_outer.result 2010-06-25 10:53:36 +0000
+++ b/mysql-test/r/join_outer.result 2010-08-26 13:26:03 +0000
@@ -1432,3 +1432,41 @@ SELECT t1.a FROM t1 LEFT JOIN
ON 0 WHERE t1.a OR t4.a;
a
DROP TABLE t1,t2,t3,t4;
+#
+# Bug#56254 Assertion tab->ref.use_count fails in
+# join_read_key_unlock_row() on 4-way JOIN
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+col_int_key INT,
+col_int INT,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key)
+);
+INSERT INTO t1 VALUES (6, -448724992, NULL);
+CREATE TABLE t2 (
+col_int INT,
+col_varchar_10 VARCHAR(10)
+);
+INSERT INTO t2 VALUES (6,'afasdkiyum');
+CREATE TABLE t3 (
+col_varchar_10 VARCHAR(10),
+col_int INT
+);
+CREATE TABLE t4 (
+pk INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t4 VALUES (1);
+INSERT INTO t4 VALUES (2);
+SELECT t1.col_int
+FROM t1
+LEFT JOIN t2
+LEFT JOIN t3
+JOIN t4
+ON t3.col_int = t4.pk
+ON t2.col_varchar_10 = t3.col_varchar_10
+ON t2.col_int = t1.pk
+WHERE t1.col_int_key IS NULL OR t4.pk < t3.col_int;
+col_int
+DROP TABLE t1,t2,t3,t4;
=== modified file 'mysql-test/r/join_outer_jcl6.result'
--- a/mysql-test/r/join_outer_jcl6.result 2010-06-25 10:53:36 +0000
+++ b/mysql-test/r/join_outer_jcl6.result 2010-08-26 13:26:03 +0000
@@ -1436,6 +1436,44 @@ SELECT t1.a FROM t1 LEFT JOIN
ON 0 WHERE t1.a OR t4.a;
a
DROP TABLE t1,t2,t3,t4;
+#
+# Bug#56254 Assertion tab->ref.use_count fails in
+# join_read_key_unlock_row() on 4-way JOIN
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+col_int_key INT,
+col_int INT,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key)
+);
+INSERT INTO t1 VALUES (6, -448724992, NULL);
+CREATE TABLE t2 (
+col_int INT,
+col_varchar_10 VARCHAR(10)
+);
+INSERT INTO t2 VALUES (6,'afasdkiyum');
+CREATE TABLE t3 (
+col_varchar_10 VARCHAR(10),
+col_int INT
+);
+CREATE TABLE t4 (
+pk INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t4 VALUES (1);
+INSERT INTO t4 VALUES (2);
+SELECT t1.col_int
+FROM t1
+LEFT JOIN t2
+LEFT JOIN t3
+JOIN t4
+ON t3.col_int = t4.pk
+ON t2.col_varchar_10 = t3.col_varchar_10
+ON t2.col_int = t1.pk
+WHERE t1.col_int_key IS NULL OR t4.pk < t3.col_int;
+col_int
+DROP TABLE t1,t2,t3,t4;
set optimizer_join_cache_level=default;
show variables like 'optimizer_join_cache_level';
Variable_name Value
=== modified file 'mysql-test/t/join_outer.test'
--- a/mysql-test/t/join_outer.test 2010-06-25 10:53:36 +0000
+++ b/mysql-test/t/join_outer.test 2010-08-26 13:26:03 +0000
@@ -1010,3 +1010,50 @@ eval explain $query;
eval $query;
DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # Bug#56254 Assertion tab->ref.use_count fails in
+--echo # join_read_key_unlock_row() on 4-way JOIN
+--echo #
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ col_int_key INT,
+ col_int INT,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key)
+);
+
+INSERT INTO t1 VALUES (6, -448724992, NULL);
+
+CREATE TABLE t2 (
+ col_int INT,
+ col_varchar_10 VARCHAR(10)
+);
+
+INSERT INTO t2 VALUES (6,'afasdkiyum');
+
+CREATE TABLE t3 (
+ col_varchar_10 VARCHAR(10),
+ col_int INT
+);
+
+CREATE TABLE t4 (
+ pk INT NOT NULL,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t4 VALUES (1);
+INSERT INTO t4 VALUES (2);
+
+SELECT t1.col_int
+FROM t1
+ LEFT JOIN t2
+ LEFT JOIN t3
+ JOIN t4
+ ON t3.col_int = t4.pk
+ ON t2.col_varchar_10 = t3.col_varchar_10
+ ON t2.col_int = t1.pk
+WHERE t1.col_int_key IS NULL OR t4.pk < t3.col_int;
+
+DROP TABLE t1,t2,t3,t4;
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2010-08-19 16:44:09 +0000
+++ b/sql/sql_select.cc 2010-08-26 13:26:03 +0000
@@ -16958,6 +16958,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
}
join->return_tab= join_tab;
+ join_tab->not_null_compl= TRUE;
if (join_tab->last_inner)
{
@@ -16965,7 +16966,6 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
/* Set initial state of guard variables for this table.*/
join_tab->found=0;
- join_tab->not_null_compl= 1;
/* Set first_unmatched for the last inner table of this group */
join_tab->last_inner->first_unmatched= join_tab;
@@ -17315,7 +17315,11 @@ evaluate_join_record(JOIN *join, JOIN_TA
else
{
join->thd->warning_info->inc_current_row_for_warning();
- join_tab->read_record.unlock_row(join_tab);
+ if (join_tab->not_null_compl)
+ {
+ /* a NULL-complemented row is not in a table so cannot be locked */
+ join_tab->read_record.unlock_row(join_tab);
+ }
}
}
else
@@ -17326,7 +17330,8 @@ evaluate_join_record(JOIN *join, JOIN_TA
*/
join->examined_rows++;
join->thd->warning_info->inc_current_row_for_warning();
- join_tab->read_record.unlock_row(join_tab);
+ if (join_tab->not_null_compl)
+ join_tab->read_record.unlock_row(join_tab);
}
DBUG_RETURN(NESTED_LOOP_OK);
}
Attachment: [text/bzr-bundle] bzr/guilhem@mysql.com-20100826132603-mx77f3foc0ic4e49.bundle
| Thread |
|---|
| • bzr push into mysql-next-mr-bugfixing branch (guilhem:3231 to 3232) Bug#56254 | Guilhem Bichot | 1 Sep |