From: Dmitry Lenev Date: December 14 2010 3:44pm Subject: bzr push into mysql-trunk-bugfixing branch (Dmitry.Lenev:3400 to 3401) Bug#27480 List-Archive: http://lists.mysql.com/commits/126794 X-Bug: 27480 Message-Id: <20101214154406.A15B21E5243@mockturtle> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3401 Dmitry Lenev 2010-12-14 Prerequisite patch for Bug#27480 (Extend CREATE TEMPORARY TABLES privilege to allow temp table operations). Review fixes in progress. Polish handling of OT_TEMPORARY_ONLY flag and streamline process of table opening. modified: sql/sql_base.cc 3400 Dmitry Lenev 2010-12-14 Prerequisite patch for Bug#27480 (Extend CREATE TEMPORARY TABLES privilege to allow temp table operations). Review fixes in progress. Simplify opening of temporary tables. Get rid of duplicated code. modified: mysql-test/r/merge.result mysql-test/t/merge.test sql/sp_head.cc sql/sql_admin.cc sql/sql_base.cc sql/sql_base.h sql/sql_handler.cc sql/sql_parse.cc sql/sql_prepare.cc sql/sql_show.cc sql/sql_table.cc sql/sql_update.cc === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2010-12-14 09:15:37 +0000 +++ b/sql/sql_base.cc 2010-12-14 15:31:57 +0000 @@ -4290,35 +4290,47 @@ open_and_process_table(THD *thd, LEX *le error= TRUE; goto end; } - - /* - If this TABLE_LIST object has an associated open TABLE object - (TABLE_LIST::table is not NULL), that TABLE object must be a pre-opened - temporary table. - */ - if (tables->table) - { - DBUG_ASSERT(is_temporary_table(tables->table)); - goto process_table; - } - - /* - If we're in CREATE TEMPORARY TABLE statement, we should not proceed - to the actual opening. - */ - if (tables->open_type == OT_TEMPORARY_ONLY) - DBUG_RETURN(FALSE); - DBUG_PRINT("tcache", ("opening table: '%s'.'%s' item: %p", tables->db, tables->table_name, tables)); //psergey: invalid read of size 1 here (*counter)++; - /* Not a placeholder: must be a base table or a view. Let us open it. */ - DBUG_ASSERT(!tables->table); + /* Not a placeholder: must be a base/temporary table or a view. Let us open it. */ - if (tables->prelocking_placeholder) + if (tables->table) { /* + If this TABLE_LIST object has an associated open TABLE object + (TABLE_LIST::table is not NULL), that TABLE object must be a pre-opened + temporary table. + */ + DBUG_ASSERT(is_temporary_table(tables->table)); + } + else if (tables->open_type == OT_TEMPORARY_ONLY) + { + /* + OT_TEMPORARY_ONLY means that we are in CREATE TEMPORARY TABLE statement. + Also such table list element can't correspond to prelocking placeholder + or to underlying table of merge table. + So existing temporary table should have been preopened by this moment + and we can simply continue without trying to open temporary or base + table. + */ + DBUG_ASSERT(tables->open_strategy); + DBUG_ASSERT(!tables->prelocking_placeholder); + DBUG_ASSERT(!tables->parent_l); + } + else if (tables->prelocking_placeholder) + { + /* + For the tables added by the pre-locking code, attempt to open + the table but fail silently if the table does not exist. + The real failure will occur when/if a statement attempts to use + that table. + */ + No_such_table_error_handler no_such_table_handler; + thd->push_internal_handler(&no_such_table_handler); + + /* We're opening a table from the prelocking list. Since this table list element might have been added after pre-opening @@ -4343,42 +4355,26 @@ open_and_process_table(THD *thd, LEX *le */ error= open_temporary_table(thd, tables); - if (error) - goto end; - - if (tables->table) - goto process_table; + if (!error && !tables->table) + error= open_table(thd, tables, new_frm_mem, ot_ctx); - /* - For the tables added by the pre-locking code, attempt to open - the table but fail silently if the table does not exist. - The real failure will occur when/if a statement attempts to use - that table. - */ - No_such_table_error_handler no_such_table_handler; - thd->push_internal_handler(&no_such_table_handler); - error= open_table(thd, tables, new_frm_mem, ot_ctx); thd->pop_internal_handler(); safe_to_ignore_table= no_such_table_handler.safely_trapped_errors(); } else { - /* - Even if we are opening table not from the prelocking list we - still might need to look for a temporary table if this table - list element corresponds to underlying table of a merge table. - */ if (tables->parent_l) { + /* + Even if we are opening table not from the prelocking list we + still might need to look for a temporary table if this table + list element corresponds to underlying table of a merge table. + */ error= open_temporary_table(thd, tables); - - if (error) - goto end; - - if (tables->table) - goto process_table; } - error= open_table(thd, tables, new_frm_mem, ot_ctx); + + if (!error && !tables->table) + error= open_table(thd, tables, new_frm_mem, ot_ctx); } free_root(new_frm_mem, MYF(MY_KEEP_PREALLOC)); @@ -4427,7 +4423,6 @@ open_and_process_table(THD *thd, LEX *le goto process_view_routines; } -process_table: /* Special types of open can succeed but still don't set TABLE_LIST::table to anything. @@ -6016,6 +6011,12 @@ bool open_temporary_table(THD *thd, TABL if (!table) { + if (tl->open_type == OT_TEMPORARY_ONLY && + tl->open_strategy == TABLE_LIST::OPEN_NORMAL) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), tl->db, tl->table_name); + DBUG_RETURN(TRUE); + } DBUG_RETURN(FALSE); } No bundle (reason: useless for push emails).