From 7efdc62f9d6c0a4846511f304521d374c7e30c79 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Sep 2006 23:11:45 +0400 Subject: [PATCH] BUG#21081: SELECT inside stored procedure returns wrong results Re-execution of a parametrized prepared statement or a stored routine with a SELECT that use LEFT JOIN with second table having only one row could yield incorrect result. The problem appeared only for left joins with second table having only one row (aka const table) and equation conditions in ON or WHERE clauses that depend on the argument passed. Once the condition was false for second const table, a NULL row was created for it, and any field involved got NULL-value flag, which then was never reset. The cause of the problem was that Item_field::null_value could be set without being reset for re-execution. The solution is to reset Item_field::null_value in Item_field::cleanup(). mysql-test/r/ps.result: Add result for bug#21081: SELECT inside stored procedure returns wrong results. mysql-test/t/ps.test: Add test case for bug#21081: SELECT inside stored procedure returns wrong results. sql/item.cc: Reset Item_field::null_value flag for re-execution. --- mysql-test/r/ps.result | 21 +++++++++++++++++++++ mysql-test/t/ps.test | 27 +++++++++++++++++++++++++++ sql/item.cc | 1 + 3 files changed, 49 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 080187cfa7b..059a8fe6aa2 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1311,4 +1311,25 @@ EXECUTE stmt USING @a; i j i i j DEALLOCATE PREPARE stmt; DROP TABLE IF EXISTS t1, t2, t3; +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1 (i INT KEY); +CREATE TABLE t2 (i INT); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (1); +PREPARE stmt FROM "SELECT t2.i FROM t1 LEFT JOIN t2 ON t2.i = t1.i + WHERE t1.i = ?"; +SET @arg= 1; +EXECUTE stmt USING @arg; +i +1 +SET @arg= 2; +EXECUTE stmt USING @arg; +i +NULL +SET @arg= 1; +EXECUTE stmt USING @arg; +i +1 +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2; End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 5b2e37ecc94..692db191cf7 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1358,4 +1358,31 @@ DEALLOCATE PREPARE stmt; DROP TABLE IF EXISTS t1, t2, t3; +# +# BUG#21081: SELECT inside stored procedure returns wrong results +# +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE TABLE t1 (i INT KEY); +CREATE TABLE t2 (i INT); + +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (1); + +PREPARE stmt FROM "SELECT t2.i FROM t1 LEFT JOIN t2 ON t2.i = t1.i + WHERE t1.i = ?"; + +SET @arg= 1; +EXECUTE stmt USING @arg; +SET @arg= 2; +EXECUTE stmt USING @arg; +SET @arg= 1; +EXECUTE stmt USING @arg; + +DEALLOCATE PREPARE stmt; +DROP TABLE t1, t2; + + --echo End of 5.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 34e5e2da165..7a4770731ea 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3744,6 +3744,7 @@ void Item_field::cleanup() I.e. we can drop 'field'. */ field= result_field= 0; + null_value= FALSE; DBUG_VOID_RETURN; }