Commit 7efdc62f authored by unknown's avatar unknown

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.
parent 1a22b9c1
......@@ -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.
......@@ -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.
......@@ -3744,6 +3744,7 @@ void Item_field::cleanup()
I.e. we can drop 'field'.
*/
field= result_field= 0;
null_value= FALSE;
DBUG_VOID_RETURN;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment