#At file:///export/home/jl208045/mysql/mysql-5.5-59299/ based on revid:jorgen.loland@stripped
3257 Jorgen Loland 2011-02-18
BUG#11766234: ASSERT (TABLE_REF->TABLE || TABLE_REF->VIEW)
FAILS IN SET_FIELD_ITERATOR
(Former 59299)
When a PROCEDURE does a natural join, resolving of which columns are
used in the join is done only once; consecutive CALLs to the procedure
will reuse this information:
CREATE PROCEDURE proc() SELECT * FROM t1 NATURAL JOIN v1;
CALL proc(); <- natural join columns resolved here
CALL proc(); <- reuse resolved NJ columns from first CALL
The second CALL knows that it can reuse the resolved NJ columns because
the first CALL sets st_select_lex::first_natural_join_processing=false.
The problem in this bug was that the table the view v1 depends on
changed between CREATE PROCEDURE and the first CALL:
CREATE PROCEDURE...
ALTER TABLE t2 CHANGE COLUMN a b CHAR;
CALL proc(); <- error when resolving natural join columns
CALL proc(); <- tries to reuse from first CALL => crash
The fix for this bug is to set first_natural_join_processing= FALSE iff
the natural join columns resolving was successful.
@ mysql-test/r/sp.result
Add test for bug 11766234
@ mysql-test/t/sp.test
Add test for bug 11766234
@ sql/sql_base.cc
Set first_natural_join_processing= FALSE iff the natural join columns resolving was successful.
modified:
mysql-test/r/sp.result
mysql-test/t/sp.test
sql/sql_base.cc
=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result 2010-07-30 15:28:36 +0000
+++ b/mysql-test/r/sp.result 2011-02-18 14:57:48 +0000
@@ -7161,6 +7161,26 @@ init_connect
SET @@GLOBAL.init_connect= @old_init_connect;
DROP PROCEDURE p2;
DROP PROCEDURE p5;
+#
+# BUG#11766234: 59299: ASSERT (TABLE_REF->TABLE || TABLE_REF->VIEW)
+# FAILS IN SET_FIELD_ITERATOR
+#
+CREATE TABLE t1 (i INT, a INT);
+CREATE TABLE t2 (j INT, a INT);
+INSERT INTO t1 VALUES (1,1), (2,2);
+INSERT INTO t2 VALUES (2,2), (3,3);
+CREATE VIEW v1 AS SELECT a FROM t2;
+CREATE PROCEDURE proc() SELECT * FROM t1 NATURAL JOIN v1;
+ALTER TABLE t2 CHANGE COLUMN a b CHAR;
+
+CALL proc();
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+CALL proc();
+ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
+
+DROP TABLE t1,t2;
+DROP VIEW v1;
+DROP PROCEDURE proc;
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test 2010-07-30 15:28:36 +0000
+++ b/mysql-test/t/sp.test 2011-02-18 14:57:48 +0000
@@ -8376,6 +8376,30 @@ SET @@GLOBAL.init_connect= @old_init_con
DROP PROCEDURE p2;
DROP PROCEDURE p5;
+--echo #
+--echo # BUG#11766234: 59299: ASSERT (TABLE_REF->TABLE || TABLE_REF->VIEW)
+--echo # FAILS IN SET_FIELD_ITERATOR
+--echo #
+
+CREATE TABLE t1 (i INT, a INT);
+CREATE TABLE t2 (j INT, a INT);
+INSERT INTO t1 VALUES (1,1), (2,2);
+INSERT INTO t2 VALUES (2,2), (3,3);
+CREATE VIEW v1 AS SELECT a FROM t2;
+CREATE PROCEDURE proc() SELECT * FROM t1 NATURAL JOIN v1;
+ALTER TABLE t2 CHANGE COLUMN a b CHAR;
+
+--echo
+--error ER_VIEW_INVALID
+CALL proc();
+--error ER_VIEW_INVALID
+CALL proc();
+
+--echo
+DROP TABLE t1,t2;
+DROP VIEW v1;
+DROP PROCEDURE proc;
+
--echo # ------------------------------------------------------------------
--echo # -- End of 5.1 tests
--echo # ------------------------------------------------------------------
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2011-01-11 11:33:28 +0000
+++ b/sql/sql_base.cc 2011-02-18 14:57:48 +0000
@@ -7569,9 +7569,10 @@ static bool setup_natural_join_row_types
List<TABLE_LIST> *from_clause,
Name_resolution_context *context)
{
+ DBUG_ENTER("setup_natural_join_row_types");
thd->where= "from clause";
if (from_clause->elements == 0)
- return FALSE; /* We come here in the case of UNIONs. */
+ DBUG_RETURN(false); /* We come here in the case of UNIONs. */
List_iterator_fast<TABLE_LIST> table_ref_it(*from_clause);
TABLE_LIST *table_ref; /* Current table reference. */
@@ -7582,8 +7583,6 @@ static bool setup_natural_join_row_types
bool save_first_natural_join_processing=
context->select_lex->first_natural_join_processing;
- context->select_lex->first_natural_join_processing= FALSE;
-
/* Note that tables in the list are in reversed order */
for (left_neighbor= table_ref_it++; left_neighbor ; )
{
@@ -7596,10 +7595,9 @@ static bool setup_natural_join_row_types
*/
if (save_first_natural_join_processing)
{
- context->select_lex->first_natural_join_processing= FALSE;
if (store_top_level_join_columns(thd, table_ref,
left_neighbor, right_neighbor))
- return TRUE;
+ DBUG_RETURN(true);
if (left_neighbor)
{
TABLE_LIST *first_leaf_on_the_right;
@@ -7619,8 +7617,9 @@ static bool setup_natural_join_row_types
DBUG_ASSERT(right_neighbor);
context->first_name_resolution_table=
right_neighbor->first_leaf_for_name_resolution();
+ context->select_lex->first_natural_join_processing= FALSE;
- return FALSE;
+ DBUG_RETURN (false);
}
Attachment: [text/bzr-bundle] bzr/jorgen.loland@oracle.com-20110218145748-4x6kp1rqb4hh0ryw.bundle