summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_berkeley.cc26
-rw-r--r--sql/ha_berkeley.h1
-rw-r--r--sql/handler.h2
-rw-r--r--sql/sql_base.cc22
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_select.cc6
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;
}