summaryrefslogtreecommitdiff
path: root/sql/sql_update.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-10-07 10:50:13 +0300
committerunknown <monty@mysql.com>2004-10-07 10:50:13 +0300
commit96e7be58c86335d68c5c79b750244e2762d6e319 (patch)
tree2ca781cd075a86d68ada5b4565202c8f62a8d84a /sql/sql_update.cc
parentbbab9ec678f9e8a0309f0b018cf6d22cd93acf84 (diff)
downloadmariadb-git-96e7be58c86335d68c5c79b750244e2762d6e319.tar.gz
After merge fixes
Some bigger code changes was necessary becasue of the multi-table-update and the new HANDLER code include/hash.h: Added back function that's was used in 4.0 mysql-test/r/delete.result: Update results after merge mysql-test/r/flush_table.result: Update results after merge mysql-test/r/func_str.result: Update results after merge mysql-test/r/handler.result: Update results after merge Change is big becasue in MySQL 4.1 you are not allowed to qualify the handler alias with a databasename mysql-test/r/multi_update.result: More startup cleanups mysql-test/r/rename.result: More startup-cleanups mysql-test/r/select.result: More startup cleanups mysql-test/r/show_check.result: More startup-cleanups mysql-test/t/ctype_latin1_de.test: Cleanup mysql-test/t/derived.test: Portability fix mysql-test/t/handler.test: Update results after merge Change is big becasue in MySQL 4.1 you are not allowed to qualify the handler alias with a databasename mysql-test/t/multi_update.test: More startup cleanups mysql-test/t/range.test: More comments mysql-test/t/rename.test: More startup cleanups mysql-test/t/select.test: More startup cleanups mysql-test/t/show_check.test: More startup cleanups mysql-test/t/type_timestamp.test: Add back test deleted during merge sql/item_cmpfunc.cc: After merge fixes sql/item_func.cc: Remove compiler warning sql/mysql_priv.h: After merge fixes sql/mysqld.cc: After merge fixes sql/sql_acl.cc: More debugging sql/sql_base.cc: After merge fixes (This fix was needed bacause of multi-table-update reopens tables) sql/sql_handler.cc: After merge fixes sql/sql_lex.h: After merge fixes sql/sql_select.cc: After merge fixes sql/sql_show.cc: After merge fixes sql/sql_table.cc: After merge fixes Simple cleanup of mysql_discard_or_import_tablespace sql/sql_update.cc: After merge fixes Rework mysql_multi_update to take into account derived tables. sql/sql_yacc.yy: After merge fixes
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r--sql/sql_update.cc37
1 files changed, 28 insertions, 9 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 25d94d6d039..d3597f274dc 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -303,6 +303,7 @@ int mysql_update(THD *thd,
else if (handle_duplicates != DUP_IGNORE ||
error != HA_ERR_FOUND_DUPP_KEY)
{
+ thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0));
error= 1;
break;
@@ -484,6 +485,8 @@ int mysql_multi_update(THD *thd,
TABLE_LIST *tl;
TABLE_LIST *update_list= (TABLE_LIST*) thd->lex->select_lex.table_list.first;
List<Item> total_list;
+ const bool using_lock_tables= thd->locked_tables != 0;
+ bool initialized_dervied= 0;
DBUG_ENTER("mysql_multi_update");
select_lex->select_limit= HA_POS_ERROR;
@@ -495,15 +498,24 @@ int mysql_multi_update(THD *thd,
for (;;)
{
table_map update_tables, derived_tables=0;
- uint tnr, counter;
+ uint tnr, table_count;
- if ((res=open_tables(thd,table_list, &counter)))
+ if ((res=open_tables(thd, table_list, &table_count)))
DBUG_RETURN(res);
/* Only need to call lock_tables if we are not using LOCK TABLES */
- if (!using_lock_tables && ((res= lock_tables(thd, table_list))))
+ if (!using_lock_tables &&
+ ((res= lock_tables(thd, table_list, table_count))))
DBUG_RETURN(res);
+ if (!initialized_dervied)
+ {
+ initialized_dervied= 1;
+ relink_tables_for_derived(thd);
+ if ((res= mysql_handle_derived(thd->lex)))
+ DBUG_RETURN(res);
+ }
+
/*
Ensure that we have update privilege for all tables and columns in the
SET part
@@ -558,7 +570,7 @@ int mysql_multi_update(THD *thd,
DBUG_RETURN(-1);
}
DBUG_PRINT("info",("setting table `%s` for update", tl->alias));
- tl->lock_type= thd->lex.lock_option;
+ tl->lock_type= thd->lex->multi_lock_option;
tl->updating= 1;
}
else
@@ -569,6 +581,8 @@ int mysql_multi_update(THD *thd,
}
if (tl->derived)
derived_tables|= table->map;
+ else if (!using_lock_tables)
+ tl->table->reginfo.lock_type= tl->lock_type;
}
if (thd->lex->derived_tables && (update_tables & derived_tables))
@@ -586,7 +600,7 @@ int mysql_multi_update(THD *thd,
}
/* Relock the tables with the correct modes */
- res= lock_tables(thd,table_list);
+ res= lock_tables(thd, table_list, table_count);
if (using_lock_tables)
{
if (res)
@@ -608,7 +622,7 @@ int mysql_multi_update(THD *thd,
item->cleanup();
}
}
- if (setup_fields(thd, table_list, *fields, 1, 0, 0))
+ if (setup_fields(thd, 0, update_list, *fields, 1, 0, 0))
DBUG_RETURN(-1);
/*
If lock succeded and the table map didn't change since the above lock
@@ -624,9 +638,7 @@ int mysql_multi_update(THD *thd,
close_thread_tables(thd);
}
- /*
- Setup timestamp handling
- */
+ /* Setup timestamp handling */
for (tl= update_list; tl; tl= tl->next)
{
TABLE *table= tl->table;
@@ -634,6 +646,9 @@ int mysql_multi_update(THD *thd,
if (table->timestamp_field &&
table->timestamp_field->query_id == thd->query_id)
table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+
+ /* We only need SELECT privilege for columns in the values list */
+ table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
}
if (!(result=new multi_update(thd, update_list, fields, values,
@@ -994,6 +1009,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
if (handle_duplicates != DUP_IGNORE ||
error != HA_ERR_FOUND_DUPP_KEY)
{
+ thd->fatal_error(); // Force error message
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);
}
@@ -1149,7 +1165,10 @@ int multi_update::do_updates(bool from_send_error)
err:
if (!from_send_error)
+ {
+ thd->fatal_error();
table->file->print_error(local_error,MYF(0));
+ }
(void) table->file->ha_rnd_end();
(void) tmp_table->file->ha_rnd_end();