Commit 1c6beaee authored by unknown's avatar unknown
Browse files

Fixed bug#19077: A nested materialized derived table is used before being populated.

The convert_constant_item() function converts constant items to ints on
prepare phase to optimize execution speed. In this case it tries to evaluate
subselect which contains a derived table and is contained in a derived table. 
All derived tables are filled only after all derived tables are prepared.
So evaluation of subselect with derived table at the prepare phase will
return a wrong result.

A new flag with_subselect is added to the Item class. It indicates that
expression which this item represents is a subselect or contains a subselect.
It is set to 0 by default. It is set to 1 in the Item_subselect constructor
for subselects.
For Item_func and Item_cond derived classes it is set after fixing any argument
in Item_func::fix_fields() and Item_cond::fix_fields accordingly.
The convert_constant_item() function now doesn't convert a constant item
if the with_subselect flag set in it. 


mysql-test/t/view.test:
  Added test case for bug#19077: A nested materialized derived table is used before being populated.
mysql-test/t/subselect.test:
  Added test case for bug#19077: A nested materialized derived table is used before being populated.
mysql-test/r/view.result:
  Added test case for bug#19077: A nested materialized derived table is used before being populated.
mysql-test/r/subselect.result:
  Added test case for bug#19077: A nested materialized derived table is used before being populated.
sql/item_subselect.cc:
  Fixed bug#19077: A nested materialized derived table is used before being populated.
  The Item_subselect class constructor sets new with_subselect flag to 1.
sql/item_func.cc:
  Fixed bug#19077: A nested materialized derived table is used before being populated.
  
  The Item_func::fix_fields() sets new with_subselect flag from with_subselect flags of its arguments.
sql/item_cmpfunc.cc:
  Fixed bug#19077: A nested materialized derived table is used before being populated.
  The convert_constant_item() function now doesn't convert a constant item
  with the with_subselect flag set.
  The Item_cond::fix_fields() sets new with_subselect flag from with_subselect flags of its arguments.
sql/item.cc:
  Fixed bug#19077: A nested materialized derived table is used before being populated.
  Set new with_subselect flag to default value - 0 in the Item constructor.
sql/item.h:
  Fixed bug#19077: A nested materialized derived table is used before being populated.
  A new flag with_subselect is added to the Item class. It indicates that
  expression which this item represents is a subselect or contains a subselect.
  It is set to 0 by default.
parent ab9eadf2
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3177,3 +3177,9 @@ ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
DROP TABLE t1;
create table t1 (i int, j bigint);
insert into t1 values (1, 2), (2, 2), (3, 2);
select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
min(i)
1
drop table t1;
+9 −0
Original line number Diff line number Diff line
@@ -2660,3 +2660,12 @@ SELECT * FROM v1;
id	t	COUNT(*)
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (i INT, j BIGINT);
INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1;
CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 );
SELECT * FROM v2;
MIN(i)
1
DROP VIEW v2, v1;
DROP TABLE t1;
+9 −0
Original line number Diff line number Diff line
@@ -2100,3 +2100,12 @@ CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);

DROP TABLE t1;

#
# Bug#19077: A nested materialized derived table is used before being populated.
#
create table t1 (i int, j bigint);
insert into t1 values (1, 2), (2, 2), (3, 2);
select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
drop table t1;
+11 −0
Original line number Diff line number Diff line
@@ -2528,3 +2528,14 @@ SELECT * FROM v1;

DROP VIEW v1;
DROP TABLE t1;

#
# Bug#19077: A nested materialized view is used before being populated.
#
CREATE TABLE t1 (i INT, j BIGINT);
INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1;
CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 );
SELECT * FROM v2;
DROP VIEW v2, v1;
DROP TABLE t1;
+1 −0
Original line number Diff line number Diff line
@@ -304,6 +304,7 @@ Item::Item():
  marker= 0;
  maybe_null=null_value=with_sum_func=unsigned_flag=0;
  decimals= 0; max_length= 0;
  with_subselect= 0;

  /* Put item in free list so that we can free all items at end */
  THD *thd= current_thd;
Loading