diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 39cb95be9e1..056457a4786 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -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; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 4baa56070b7..557b44a11eb 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -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; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 9f4d89a7e50..3f48b648f40 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -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; + diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index ea22ada900a..1271329a520 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -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; diff --git a/sql/item.cc b/sql/item.cc index 51a2f9a24f3..44aa583aa3f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -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; diff --git a/sql/item.h b/sql/item.h index 19a57a10720..28b1f54add7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -460,6 +460,9 @@ public: my_bool is_autogenerated_name; /* indicate was name of this Item autogenerated or set by user */ DTCollation collation; + my_bool with_subselect; /* If this item is a subselect or some + of its arguments is or contains a + subselect */ // alloc & destruct is done as start of select using sql_alloc Item(); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 54e281a1f14..ca5d79973e5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -204,10 +204,28 @@ longlong Item_func_nop_all::val_int() /* - Convert a constant expression or string to an integer. - This is done when comparing DATE's of different formats and - also when comparing bigint to strings (in which case the string - is converted once to a bigint). + Convert a constant item to an int and replace the original item + + SYNOPSIS + convert_constant_item() + thd thread handle + field item will be converted using the type of this field + item [in/out] reference to the item to convert + + DESCRIPTION + The function converts a constant expression or string to an integer. + On successful conversion the original item is substituted for the + result of the item evaluation. + This is done when comparing DATE/TIME of different formats and + also when comparing bigint to strings (in which case strings + are converted to bigints). + + NOTES + This function is called only at prepare stage. + As all derived tables are filled only after all derived tables + are prepared we do not evaluate items with subselects here because + they can contain derived tables and thus we may attempt to use a + table that has not been populated yet. RESULT VALUES 0 Can't convert item @@ -216,7 +234,7 @@ longlong Item_func_nop_all::val_int() static bool convert_constant_item(THD *thd, Field *field, Item **item) { - if ((*item)->const_item()) + if (!(*item)->with_subselect && (*item)->const_item()) { /* For comparison purposes allow invalid dates like 2000-01-32 */ ulong orig_sql_mode= field->table->in_use->variables.sql_mode; @@ -2578,6 +2596,7 @@ Item_cond::fix_fields(THD *thd, Item **ref) const_item_cache= FALSE; } with_sum_func= with_sum_func || item->with_sum_func; + with_subselect|= item->with_subselect; if (item->maybe_null) maybe_null=1; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 5ef9db6f52b..2c770bec1ad 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -184,6 +184,7 @@ Item_func::fix_fields(THD *thd, Item **ref) used_tables_cache|= item->used_tables(); not_null_tables_cache|= item->not_null_tables(); const_item_cache&= item->const_item(); + with_subselect|= item->with_subselect; } } fix_length_and_dec(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 4b304725927..87ef0fc080e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -39,6 +39,7 @@ Item_subselect::Item_subselect(): engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1), engine_changed(0), changed(0) { + with_subselect= 1; reset(); /* item value is NULL if select_subselect not changed this value