From e851a9eaea77eb896c14b5d57a7acb6221fea2f9 Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Wed, 29 Nov 2006 14:52:11 +0300 Subject: [PATCH] Bug#20327: Marking of a wrong field leads to a wrong result on select with view, prepared statement and subquery. When a field of a view from an outer select is resolved the find_field_in_view function creates an Item_direct_view_ref object that references the corresponding view underlying field. After that the view_ref is marked as a dependent one. While resolving view underlying field it also get marked as a dependent one due to current_select still points to the subselect. Marking the view underlying field is wrong and lead to attaching conditions to a wrong table and thus to the wrong result of the whole statement. Now mark_select_range_as_dependent() function isn't called for fields from a view underlying table. --- mysql-test/r/ps.result | 18 ++++++++++++++++++ mysql-test/t/ps.test | 22 ++++++++++++++++++++++ sql/sql_base.cc | 6 ++++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 048c3ae46d3..2493bd372ea 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1379,4 +1379,22 @@ i 1 DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; +CREATE TABLE t1 (i INT); +CREATE VIEW v1 AS SELECT * FROM t1; +INSERT INTO t1 VALUES (1), (2); +SELECT t1.i FROM t1 JOIN v1 ON t1.i = v1.i +WHERE EXISTS (SELECT * FROM t1 WHERE v1.i = 1); +i +1 +PREPARE stmt FROM "SELECT t1.i FROM t1 JOIN v1 ON t1.i = v1.i +WHERE EXISTS (SELECT * FROM t1 WHERE v1.i = 1)"; +EXECUTE stmt; +i +1 +EXECUTE stmt; +i +1 +DEALLOCATE PREPARE stmt; +DROP VIEW v1; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index f1e8e77d94e..be77c2533e9 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1437,4 +1437,26 @@ DEALLOCATE PREPARE stmt; DROP TABLE t1, t2; +# +# BUG#20327: Marking of a wrong field leads to a wrong result on select with +# view, prepared statement and subquery. +# +CREATE TABLE t1 (i INT); +CREATE VIEW v1 AS SELECT * FROM t1; + +INSERT INTO t1 VALUES (1), (2); + +let $query = SELECT t1.i FROM t1 JOIN v1 ON t1.i = v1.i + WHERE EXISTS (SELECT * FROM t1 WHERE v1.i = 1); +eval $query; +eval PREPARE stmt FROM "$query"; +# Statement execution should return '1'. +EXECUTE stmt; +# Check re-execution. +EXECUTE stmt; + +DEALLOCATE PREPARE stmt; +DROP VIEW v1; +DROP TABLE t1; + --echo End of 5.0 tests. diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3984ceac6a9..314452fac89 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3303,6 +3303,12 @@ find_field_in_tables(THD *thd, Item_ident *item, { if (found == WRONG_GRANT) return (Field*) 0; + + /* + Only views fields should be marked as dependent, not an underlying + fields. + */ + if (!table_ref->belong_to_view) { SELECT_LEX *current_sel= thd->lex->current_select; SELECT_LEX *last_select= table_ref->select_lex;