summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-10-06 01:25:55 +0300
committerunknown <monty@mysql.com>2004-10-06 01:25:55 +0300
commit4d93bb95625131b703db76c2ad0c33fe8beeb274 (patch)
treed64d190d42d20c08e4499ef9df31759451dcfe13 /sql
parentcd430fbfb6eae25c7abfb18758c8907fa44cbd35 (diff)
parent0d76cb7ea4a20570342d51136a6da598fb553800 (diff)
downloadmariadb-git-4d93bb95625131b703db76c2ad0c33fe8beeb274.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-4.0
into mysql.com:/home/my/mysql-4.0 sql/sql_table.cc: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_myisam.cc26
-rw-r--r--sql/handler.cc2
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_table.cc6
-rw-r--r--sql/sql_update.cc110
5 files changed, 74 insertions, 72 deletions
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 2b7b8f436b1..3bfee7cdd79 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -998,32 +998,14 @@ int ha_myisam::delete_table(const char *name)
return mi_delete_table(name);
}
+
int ha_myisam::external_lock(THD *thd, int lock_type)
{
- int rc;
-
- while ((! (rc= mi_lock_database(file, !table->tmp_table ?
- lock_type : ((lock_type == F_UNLCK) ?
- F_UNLCK : F_EXTRA_LCK)))) &&
- mi_is_crashed(file) && (myisam_recover_options != HA_RECOVER_NONE))
- {
- /*
- check_and_repair() implicitly write locks the table, unless a
- LOCK TABLES is in effect. It should be safer to always write lock here.
- The implicit lock by check_and_repair() will then be a no-op.
- check_and_repair() does not restore the original lock, but unlocks the
- table. So we have to get the requested lock type again. And then to
- check, if the table has been crashed again meanwhile by another server.
- If anything fails, we break.
- */
- if (((lock_type != F_WRLCK) && (rc= mi_lock_database(file, F_WRLCK))) ||
- (rc= check_and_repair(thd)))
- break;
- }
- return rc;
+ return mi_lock_database(file, !table->tmp_table ?
+ lock_type : ((lock_type == F_UNLCK) ?
+ F_UNLCK : F_EXTRA_LCK));
}
-
THR_LOCK_DATA **ha_myisam::store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)
diff --git a/sql/handler.cc b/sql/handler.cc
index 9eb129fab45..65078a485c5 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -348,7 +348,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
if (trans == &thd->transaction.all &&
my_b_tell(&thd->transaction.trans_log))
{
- if (error= wait_if_global_read_lock(thd, 0, 0))
+ if ((error= wait_if_global_read_lock(thd, 0, 0)))
{
/*
Note that ROLLBACK [TO SAVEPOINT] does not have this test; it's
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 58d0fe9a7fa..6e782f81ae5 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -469,7 +469,7 @@ static ulong get_sort(uint count,...)
uint chars= 0;
uint wild_pos= 0; /* first wildcard position */
- if (start= str)
+ if ((start= str))
{
for (; *str ; str++)
{
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index a15f8b65006..520cce23797 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2209,11 +2209,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
DBUG_RETURN(-1); /* purecov: inspected */
if (to->file->external_lock(thd, F_WRLCK))
- {
- /* We must always unlock, even when lock failed. */
- (void) to->file->external_lock(thd, F_UNLCK);
DBUG_RETURN(-1);
- }
to->file->extra(HA_EXTRA_WRITE_CACHE);
from->file->info(HA_STATUS_VARIABLE);
to->file->deactivate_non_unique_index(from->file->records);
@@ -2313,11 +2309,11 @@ copy_data_between_tables(TABLE *from,TABLE *to,
error=1;
if (ha_commit(thd))
error=1;
+
err:
free_io_cache(from);
*copied= found_count;
*deleted=delete_count;
- /* we must always unlock the table on return. */
if (to->file->external_lock(thd,F_UNLCK))
error=1;
DBUG_RETURN(error > 0 ? -1 : 0);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index a17742df03b..cdcc90e8651 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -387,6 +387,24 @@ err:
***************************************************************************/
/*
+ Get table map for list of Item_field
+*/
+
+static table_map get_table_map(List<Item> *items)
+{
+ List_iterator_fast<Item> item_it(*items);
+ Item_field *item;
+ table_map map= 0;
+
+ while ((item= (Item_field *) item_it++))
+ map|= item->used_tables();
+ DBUG_PRINT("info",("table_map: 0x%08x", map));
+ return map;
+}
+
+
+
+/*
Setup multi-update handling and call SELECT to do the join
*/
@@ -401,59 +419,45 @@ int mysql_multi_update(THD *thd,
int res;
multi_update *result;
TABLE_LIST *tl;
- const bool locked= !(thd->locked_tables);
+ const bool using_lock_tables= thd->locked_tables != 0;
DBUG_ENTER("mysql_multi_update");
+ thd->select_limit= HA_POS_ERROR;
+
for (;;)
{
- table_map update_map= 0;
- int tnr= 0;
+ table_map update_map;
+ int tnr;
if ((res= open_tables(thd, table_list)))
DBUG_RETURN(res);
- /*
- Only need to call lock_tables if (thd->locked_tables == NULL)
- */
- if (locked && ((res= lock_tables(thd, table_list))))
+ /* Only need to call lock_tables if we are not using LOCK TABLES */
+ if (!using_lock_tables && ((res= lock_tables(thd, table_list))))
DBUG_RETURN(res);
- thd->select_limit=HA_POS_ERROR;
-
/*
Ensure that we have update privilege for all tables and columns in the
SET part
While we are here, initialize the table->map field.
*/
- for (tl= table_list ; tl ; tl=tl->next)
+ for (tl= table_list,tnr=0 ; tl ; tl=tl->next)
{
TABLE *table= tl->table;
table->grant.want_privilege= (UPDATE_ACL & ~table->grant.privilege);
table->map= (table_map) 1 << (tnr++);
}
- if (!setup_fields(thd, table_list, *fields, 1, 0, 0))
- {
- List_iterator_fast<Item> field_it(*fields);
- Item_field *item;
-
- while ((item= (Item_field *) field_it++))
- update_map|= item->used_tables();
-
- DBUG_PRINT("info",("update_map=0x%08x", update_map));
- }
- else
+ if (setup_fields(thd, table_list, *fields, 1, 0, 0))
DBUG_RETURN(-1);
- /*
- Unlock the tables in preparation for relocking
- */
- if (locked)
+ update_map= get_table_map(fields);
+
+ /* Unlock the tables in preparation for relocking */
+ if (!using_lock_tables)
{
- pthread_mutex_lock(&LOCK_open);
mysql_unlock_tables(thd, thd->lock);
thd->lock= 0;
- pthread_mutex_unlock(&LOCK_open);
}
/*
@@ -474,26 +478,48 @@ int mysql_multi_update(THD *thd,
tl->lock_type= TL_READ;
tl->updating= 0;
}
- if (locked)
+ if (!using_lock_tables)
tl->table->reginfo.lock_type= tl->lock_type;
}
+ /* Relock the tables with the correct modes */
+ res= lock_tables(thd,table_list);
+ if (using_lock_tables)
+ {
+ if (res)
+ DBUG_RETURN(res);
+ break; // Don't have to do setup_field()
+ }
+
/*
- Relock the tables
+ We must setup fields again as the file may have been reopened
+ during lock_tables
*/
- if (!(res=lock_tables(thd,table_list)))
- break;
-
- if (!locked)
- DBUG_RETURN(res);
- List_iterator_fast<Item> field_it(*fields);
- Item_field *item;
+ {
+ List_iterator_fast<Item> field_it(*fields);
+ Item_field *item;
- while ((item= (Item_field *) field_it++))
- /* item->cleanup(); XXX Use this instead in MySQL 4.1+ */
- item->field= item->result_field= 0;
+ while ((item= (Item_field *) field_it++))
+#if MYSQL_VERSION < 40100
+ item->field= item->result_field= 0;
+#else
+ item->cleanup();
+#endif
+ }
+ if (setup_fields(thd, table_list, *fields, 1, 0, 0))
+ DBUG_RETURN(-1);
+ /*
+ If lock succeded and the table map didn't change since the above lock
+ we can continue.
+ */
+ if (!res && update_map == get_table_map(fields))
+ break;
+ /*
+ There was some very unexpected changes in the table definition between
+ open tables and lock tables. Close tables and try again.
+ */
close_thread_tables(thd);
}
@@ -548,7 +574,7 @@ int multi_update::prepare(List<Item> &not_used_values)
{
TABLE_LIST *table_ref;
SQL_LIST update;
- table_map tables_to_update= 0;
+ table_map tables_to_update;
Item_field *item;
List_iterator_fast<Item> field_it(*fields);
List_iterator_fast<Item> value_it(*values);
@@ -559,8 +585,7 @@ int multi_update::prepare(List<Item> &not_used_values)
thd->cuted_fields=0L;
thd->proc_info="updating main table";
- while ((item= (Item_field *) field_it++))
- tables_to_update|= item->used_tables();
+ tables_to_update= get_table_map(fields);
if (!tables_to_update)
{
@@ -624,7 +649,6 @@ int multi_update::prepare(List<Item> &not_used_values)
/* Split fields into fields_for_table[] and values_by_table[] */
- field_it.rewind();
while ((item= (Item_field *) field_it++))
{
Item *value= value_it++;