diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_berkeley.cc | 26 | ||||
-rw-r--r-- | sql/ha_berkeley.h | 1 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 22 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 |
6 files changed, 52 insertions, 6 deletions
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 9dbd7b6c998..4b4894ebcd5 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -41,10 +41,9 @@ from the updated tables. Testing of: - - LOCK TABLES - Mark tables that participate in a transaction so that they are not closed during the transaction. We need to test what happens if - MySQL closes a table that is updated by a not commit transaction. + MySQL closes a table that is updated by a not commited transaction. */ @@ -1701,12 +1700,35 @@ int ha_berkeley::external_lock(THD *thd, int lock_type) DBUG_PRINT("trans",("commiting non-updating transaction")); error=txn_commit((DB_TXN*) thd->transaction.stmt.bdb_tid,0); thd->transaction.stmt.bdb_tid=0; + transaction=0; } } } DBUG_RETURN(error); } + +/* + When using LOCK TABLE's external_lock is only called when the actual + TABLE LOCK is done. + Under LOCK TABLES, each used tables will force a call to start_stmt. +*/ + +int ha_berkeley::start_stmt(THD *thd) +{ + int error=0; + DBUG_ENTER("ha_berkeley::start_stmt"); + if (!thd->transaction.stmt.bdb_tid) + { + error=txn_begin(db_env, (DB_TXN*) thd->transaction.all.bdb_tid, + (DB_TXN**) &thd->transaction.stmt.bdb_tid, + 0); + transaction= (DB_TXN*) thd->transaction.stmt.bdb_tid; + } + DBUG_RETURN(error); +} + + /* The idea with handler::store_lock() is the following: diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 9724d128b1f..9e657d72da1 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -136,6 +136,7 @@ class ha_berkeley: public handler int extra(enum ha_extra_function operation); int reset(void); int external_lock(THD *thd, int lock_type); + int start_stmt(THD *thd); void position(byte *record); int analyze(THD* thd,HA_CHECK_OPT* check_opt); int optimize(THD* thd, HA_CHECK_OPT* check_opt); diff --git a/sql/handler.h b/sql/handler.h index 638529ab882..c7df6e2a915 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -265,6 +265,7 @@ public: virtual int extra(enum ha_extra_function operation)=0; virtual int reset()=0; virtual int external_lock(THD *thd, int lock_type)=0; + virtual int start_stmt(THD *thd) {return 0;} virtual int delete_all_rows(); virtual longlong get_auto_increment(); virtual void update_create_info(HA_CREATE_INFO *create_info) {} @@ -344,6 +345,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, bool update_create_info); int ha_delete_table(enum db_type db_type, const char *path); void ha_key_cache(void); +int ha_start_stmt(THD *thd); int ha_commit_trans(THD *thd, THD_TRANS *trans); int ha_rollback_trans(THD *thd, THD_TRANS *trans); int ha_autocommit_or_rollback(THD *thd, int error); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 49c858b7a16..134449fd20a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1399,6 +1399,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) &refresh)) && refresh) ; if (table) { + int error; table_list->table=table; table->grant= table_list->grant; if (thd->locked_tables) @@ -1410,7 +1411,12 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, ER(ER_TABLE_NOT_LOCKED_FOR_WRITE), MYF(0),table_list->name); - DBUG_RETURN(0); + table=0; + } + else if ((error=table->file->start_stmt(thd))) + { + table->file->print_error(error,MYF(0)); + table=0; } thd->proc_info=0; DBUG_RETURN(table); @@ -1437,10 +1443,10 @@ int open_and_lock_tables(THD *thd,TABLE_LIST *tables) int lock_tables(THD *thd,TABLE_LIST *tables) { + TABLE_LIST *table; if (tables && !thd->locked_tables) { uint count=0; - TABLE_LIST *table; for (table = tables ; table ; table=table->next) count++; TABLE **start,**ptr; @@ -1451,6 +1457,18 @@ int lock_tables(THD *thd,TABLE_LIST *tables) if (!(thd->lock=mysql_lock_tables(thd,start,count))) return -1; /* purecov: inspected */ } + else + { + for (table = tables ; table ; table=table->next) + { + int error; + if ((error=table->table->file->start_stmt(thd))) + { + table->table->file->print_error(error,MYF(0)); + return -1; + } + } + } return 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5ed17d76dff..f0cc3f9c42a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1830,6 +1830,7 @@ mysql_execute_command(void) { thd->lock=thd->locked_tables; thd->locked_tables=0; // Will be automaticly closed + end_active_trans(thd); } if (thd->global_read_lock) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 77cf20f813a..00a41a851b5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2525,7 +2525,6 @@ join_free(JOIN *join) delete tab->select; delete tab->quick; x_free(tab->cache.buff); - end_read_record(&tab->read_record); if (tab->table) { if (tab->table->key_read) @@ -2533,8 +2532,11 @@ join_free(JOIN *join) tab->table->key_read=0; tab->table->file->extra(HA_EXTRA_NO_KEYREAD); } - tab->table->file->index_end(); + /* Don't free index if we are using read_record */ + if (!tab->read_record.table) + tab->table->file->index_end(); } + end_read_record(&tab->read_record); } join->table=0; } |