From: kroki Date: February 6 2007 4:15pm Subject: bk commit into 5.1 tree (kroki:1.2417) BUG#18326 List-Archive: http://lists.mysql.com/commits/19412 X-Bug: 18326 Message-Id: <200702061615.l16GFZer011883@moonlight.home> Below is the list of changes that have just been committed into a local 5.1 repository of tomash. When tomash does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2007-02-06 19:15:26+03:00, kroki@stripped +1 -0 BUG#18326: Do not lock table for writing during prepare of statement During statement prepare phase the tables were locked as if the statement is being executed, however this is not necessary. The solution is to not lock tables on statement prepare phase. Opening tables is enough to prevent DDL on them, and during statement prepare we do not access nor modify any data. sql/sql_prepare.cc@stripped, 2007-02-06 19:15:21+03:00, kroki@stripped +40 -56 Do not lock tables on statement prepare phase. Opening tables is enough to prevent DDL on them, and during statement prepare we do not access nor modify any data. Use open_normal_and_derived_tables() for table opening. # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: kroki # Host: moonlight.home # Root: /home/tomash/src/mysql_ab/mysql-5.1-bug18326 --- 1.190/sql/sql_prepare.cc 2007-02-06 19:15:35 +03:00 +++ 1.191/sql/sql_prepare.cc 2007-02-06 19:15:35 +03:00 @@ -1120,38 +1120,20 @@ static int mysql_test_update(Prepared_st bool need_reopen; DBUG_ENTER("mysql_test_update"); - if (update_precheck(thd, table_list)) + if (update_precheck(thd, table_list) || + open_normal_and_derived_tables(thd, table_list, 0)) goto error; - for ( ; ; ) + if (table_list->multitable_view) { - if (open_tables(thd, &table_list, &table_count, 0)) - goto error; - - if (table_list->multitable_view) - { - DBUG_ASSERT(table_list->view != 0); - DBUG_PRINT("info", ("Switch to multi-update")); - /* pass counter value */ - thd->lex->table_count= table_count; - /* convert to multiupdate */ - DBUG_RETURN(2); - } - - if (!lock_tables(thd, table_list, table_count, &need_reopen)) - break; - if (!need_reopen) - goto error; - close_tables_for_reopen(thd, &table_list); + DBUG_ASSERT(table_list->view != 0); + DBUG_PRINT("info", ("Switch to multi-update")); + /* pass counter value */ + thd->lex->table_count= table_count; + /* convert to multiupdate */ + DBUG_RETURN(2); } - /* - thd->fill_derived_tables() is false here for sure (because it is - preparation of PS, so we even do not check it). - */ - if (mysql_handle_derived(thd->lex, &mysql_derived_prepare)) - goto error; - #ifndef NO_EMBEDDED_ACCESS_CHECKS /* TABLE_LIST contain right privilages request */ want_privilege= table_list->grant.want_privilege; @@ -1209,7 +1191,7 @@ static bool mysql_test_delete(Prepared_s DBUG_ENTER("mysql_test_delete"); if (delete_precheck(thd, table_list) || - open_and_lock_tables(thd, table_list)) + open_normal_and_derived_tables(thd, table_list, 0)) goto error; if (!table_list->table) @@ -1268,7 +1250,7 @@ static int mysql_test_select(Prepared_st goto error; } - if (open_and_lock_tables(thd, tables)) + if (open_normal_and_derived_tables(thd, tables, 0)) goto error; thd->used_tables= 0; // Updated by setup_fields @@ -1329,7 +1311,7 @@ static bool mysql_test_do_fields(Prepare if (tables && check_table_access(thd, SELECT_ACL, tables, 0)) DBUG_RETURN(TRUE); - if (open_and_lock_tables(thd, tables)) + if (open_normal_and_derived_tables(thd, tables, 0)) DBUG_RETURN(TRUE); DBUG_RETURN(setup_fields(thd, 0, *values, MARK_COLUMNS_NONE, 0, 0)); } @@ -1359,7 +1341,7 @@ static bool mysql_test_set_fields(Prepar set_var_base *var; if (tables && check_table_access(thd, SELECT_ACL, tables, 0) || - open_and_lock_tables(thd, tables)) + open_normal_and_derived_tables(thd, tables, 0)) goto error; while ((var= it++)) @@ -1385,7 +1367,7 @@ error: NOTE This function won't directly open tables used in select. They should be opened either by calling function (and in this case you probably - should use select_like_stmt_test_with_open_n_lock()) or by + should use select_like_stmt_test_with_open()) or by "specific_prepare" call (like this happens in case of multi-update). RETURN VALUE @@ -1413,14 +1395,14 @@ static bool select_like_stmt_test(Prepar } /* - Check internal SELECT of the prepared command (with opening and - locking of used tables). + Check internal SELECT of the prepared command (with opening of used + tables). SYNOPSIS - select_like_stmt_test_with_open_n_lock() + select_like_stmt_test_with_open() stmt prepared statement - tables list of tables to be opened and locked - before calling specific_prepare function + tables list of tables to be opened before calling + specific_prepare function specific_prepare function of command specific prepare setup_tables_done_option options to be passed to LEX::unit.prepare() @@ -1430,19 +1412,20 @@ static bool select_like_stmt_test(Prepar */ static bool -select_like_stmt_test_with_open_n_lock(Prepared_statement *stmt, - TABLE_LIST *tables, - bool (*specific_prepare)(THD *thd), - ulong setup_tables_done_option) +select_like_stmt_test_with_open(Prepared_statement *stmt, + TABLE_LIST *tables, + bool (*specific_prepare)(THD *thd), + ulong setup_tables_done_option) { - DBUG_ENTER("select_like_stmt_test_with_open_n_lock"); + DBUG_ENTER("select_like_stmt_test_with_open"); /* - We should not call LEX::unit.cleanup() after this open_and_lock_tables() - call because we don't allow prepared EXPLAIN yet so derived tables will - clean up after themself. + We should not call LEX::unit.cleanup() after this + open_normal_and_derived_tables() call because we don't allow + prepared EXPLAIN yet so derived tables will clean up after + themself. */ - if (open_and_lock_tables(stmt->thd, tables)) + if (open_normal_and_derived_tables(stmt->thd, tables, 0)) DBUG_RETURN(TRUE); DBUG_RETURN(select_like_stmt_test(stmt, specific_prepare, @@ -1481,7 +1464,7 @@ static bool mysql_test_create_table(Prep if (select_lex->item_list.elements) { select_lex->context.resolve_in_select_list= TRUE; - res= select_like_stmt_test_with_open_n_lock(stmt, tables, 0, 0); + res= select_like_stmt_test_with_open(stmt, tables, 0, 0); } /* put tables back for PS rexecuting */ @@ -1541,9 +1524,9 @@ static bool mysql_test_multidelete(Prepa } if (multi_delete_precheck(stmt->thd, tables) || - select_like_stmt_test_with_open_n_lock(stmt, tables, - &mysql_multi_delete_prepare, - OPTION_SETUP_TABLES_DONE)) + select_like_stmt_test_with_open(stmt, tables, + &mysql_multi_delete_prepare, + OPTION_SETUP_TABLES_DONE)) goto error; if (!tables->table) { @@ -1559,15 +1542,16 @@ error: /* Wrapper for mysql_insert_select_prepare, to make change of local tables - after open_and_lock_tables() call. + after open_normal_and_derived_tables() call. SYNOPSIS mysql_insert_select_prepare_tester() thd thread handle NOTE - We need to remove the first local table after open_and_lock_tables, - because mysql_handle_derived uses local tables lists. + We need to remove the first local table after + open_normal_and_derived_tables(), because mysql_handle_derived + uses local tables lists. */ static bool mysql_insert_select_prepare_tester(THD *thd) @@ -1624,9 +1608,9 @@ static bool mysql_test_insert_select(Pre DBUG_ASSERT(first_local_table != 0); res= - select_like_stmt_test_with_open_n_lock(stmt, tables, - &mysql_insert_select_prepare_tester, - OPTION_SETUP_TABLES_DONE); + select_like_stmt_test_with_open(stmt, tables, + &mysql_insert_select_prepare_tester, + OPTION_SETUP_TABLES_DONE); /* revert changes made by mysql_insert_select_prepare_tester */ lex->select_lex.table_list.first= (byte*) first_local_table; return res;