summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSinisa@sinisa.nasamreza.org <>2002-01-16 22:45:47 +0200
committerSinisa@sinisa.nasamreza.org <>2002-01-16 22:45:47 +0200
commitd71bd75fcae533c2eda9020d0e51eb8b6183f7c4 (patch)
tree0d211c58a2586081354d31eb3906bcc060663385 /sql
parent74deec5a00ece82afad41de556e12e395962f304 (diff)
downloadmariadb-git-d71bd75fcae533c2eda9020d0e51eb8b6183f7c4.tar.gz
some small changes for MULTI-TABLE updates and other little fixes
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_parse.cc124
-rw-r--r--sql/sql_update.cc32
3 files changed, 70 insertions, 88 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7b6c4f5af57..f26d808ae17 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -684,7 +684,7 @@ public:
enum enum_duplicates dupl;
uint num_of_tables, num_fields, num_updated, *save_time_stamps, *field_sequence;
int error;
- bool do_update;
+ bool do_update, not_trans_safe;
public:
multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> &fs,
enum enum_duplicates handle_duplicates,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f1b1974ac64..1f9f014fe3a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1224,8 +1224,6 @@ mysql_execute_command(void)
(table_rules_on && tables && thd->slave_thread &&
!tables_ok(thd,tables)))
DBUG_VOID_RETURN;
- if (lex->sql_command==SQLCOM_UPDATE && select_lex->table_list.elements > 1)
- lex->sql_command=SQLCOM_MULTI_UPDATE;
thread_safe_increment(com_stat[lex->sql_command],&LOCK_thread_count);
switch (lex->sql_command) {
@@ -1697,19 +1695,68 @@ mysql_execute_command(void)
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
DBUG_VOID_RETURN;
}
- res = mysql_update(thd,tables,
- select_lex->item_list,
- lex->value_list,
- select_lex->where,
- (ORDER *) select_lex->order_list.first,
- select_lex->select_limit,
- lex->duplicates,
- lex->lock_option);
+ if (select_lex->table_list.elements == 1)
+ {
+ res = mysql_update(thd,tables,
+ select_lex->item_list,
+ lex->value_list,
+ select_lex->where,
+ (ORDER *) select_lex->order_list.first,
+ select_lex->select_limit,
+ lex->duplicates,
+ lex->lock_option);
#ifdef DELETE_ITEMS
- delete select_lex->where;
+ delete select_lex->where;
#endif
- break;
+ }
+ else
+ {
+ multi_update *result;
+ uint table_count;
+ TABLE_LIST *auxi;
+ lex->sql_command=SQLCOM_MULTI_UPDATE;
+ for (auxi=(TABLE_LIST*) tables, table_count=0 ; auxi ; auxi=auxi->next)
+ {
+ table_count++;
+ auxi->lock_type=TL_WRITE;
+ }
+ if (select_lex->order_list.elements || (select_lex->select_limit && select_lex->select_limit < INT_MAX))
+ {
+ send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /// will have to come up with something better eventually
+ DBUG_VOID_RETURN;
+ }
+ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
+ if ((res=open_and_lock_tables(thd,tables)))
+ break;
+ if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) &&
+ !setup_fields(thd,tables,lex->value_list,0,0,0) && ! thd->fatal_error &&
+ (result=new multi_update(thd,tables,select_lex->item_list,lex->duplicates,
+ lex->lock_option, table_count)))
+ {
+ List <Item> total_list;
+ List_iterator <Item> field_list(select_lex->item_list);
+ List_iterator <Item> value_list(lex->value_list);
+ Item *item;
+ while ((item=field_list++))
+ total_list.push_back(item);
+ while ((item=value_list++))
+ total_list.push_back(item);
+
+ res=mysql_select(thd,tables,total_list,
+ select_lex->where,
+ (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
+ (ORDER *)NULL,
+ select_lex->options | thd->options |
+ SELECT_NO_JOIN_CACHE,
+ result);
+ delete result;
+ }
+ else
+ res= -1; // Error is not sent
+ close_thread_tables(thd);
+ }
+ break;
case SQLCOM_INSERT:
if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
@@ -1879,59 +1926,6 @@ mysql_execute_command(void)
close_thread_tables(thd);
break;
}
- case SQLCOM_MULTI_UPDATE:
- multi_update *result;
- uint table_count;
- TABLE_LIST *auxi;
- if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege))
- goto error;
- if (grant_option && check_grant(thd,UPDATE_ACL,tables))
- goto error;
- if (select_lex->item_list.elements != lex->value_list.elements)
- {
- send_error(&thd->net,ER_WRONG_VALUE_COUNT);
- DBUG_VOID_RETURN;
- }
- for (auxi=(TABLE_LIST*) tables, table_count=0 ; auxi ; auxi=auxi->next)
- {
- table_count++;
- auxi->lock_type=TL_WRITE;
- }
- if (select_lex->order_list.elements || (select_lex->select_limit && select_lex->select_limit < INT_MAX))
- {
- send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /// will have to come up with something better eventually
- DBUG_VOID_RETURN;
- }
- tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
- if ((res=open_and_lock_tables(thd,tables)))
- break;
- if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) &&
- !setup_fields(thd,tables,lex->value_list,0,0,0) && ! thd->fatal_error &&
- (result=new multi_update(thd,tables,select_lex->item_list,lex->duplicates,
- lex->lock_option, table_count)))
- {
- List <Item> total_list;
- List_iterator <Item> field_list(select_lex->item_list);
- List_iterator <Item> value_list(lex->value_list);
- Item *item;
- while ((item=field_list++))
- total_list.push_back(item);
- while ((item=value_list++))
- total_list.push_back(item);
-
- res=mysql_select(thd,tables,total_list,
- select_lex->where,
- (ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
- (ORDER *)NULL,
- select_lex->options | thd->options |
- SELECT_NO_JOIN_CACHE,
- result);
- delete result;
- }
- else
- res= -1; // Error is not sent
- close_thread_tables(thd);
- break;
case SQLCOM_DROP_TABLE:
{
if (check_table_access(thd,DROP_ACL,tables))
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index b9cf7478e0c..f6f359d1a44 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -359,6 +359,7 @@ multi_update::multi_update(THD *thd_arg, TABLE_LIST *ut, List<Item> &fs,
tmp_tables = (TABLE **)NULL;
int counter=0;
ulong timestamp_query_id;
+ not_trans_safe=false;
for (TABLE_LIST *dt=ut ; dt ; dt=dt->next,counter++)
{
TABLE *table=ut->table;
@@ -420,6 +421,9 @@ multi_update::prepare(List<Item> &values)
{
num_updated++;
table_ref->shared=1;
+ if (!not_trans_safe && !table_ref->table->file->has_transactions())
+ not_trans_safe=true;
+ table_ref->table->no_keyread=1; // to be moved if initialize_tables has to be used
break;
}
}
@@ -529,6 +533,7 @@ multi_update::~multi_update()
{
TABLE *table=table_being_updated->table;
(void)table->file->extra(HA_EXTRA_READCHECK);
+ table->no_keyread=0;
if (error)
table->time_stamp=save_time_stamps[counter];
}
@@ -629,27 +634,13 @@ bool multi_update::send_data(List<Item> &values)
return 0;
}
-
-/* Return true if some table is not transaction safe */
-
-static bool some_table_is_not_transaction_safe (TABLE_LIST *tl)
-{
- for (; tl ; tl=tl->next)
- {
- if (!(tl->table->file->has_transactions()))
- return true;
- }
- return false;
-}
-
-
void multi_update::send_error(uint errcode,const char *err)
{
/* First send error what ever it is ... */
::send_error(&thd->net,errcode,err);
/* reset used flags */
- update_tables->table->no_keyread=0;
+// update_tables->table->no_keyread=0;
/* If nothing updated return */
if (!updated)
@@ -665,8 +656,7 @@ void multi_update::send_error(uint errcode,const char *err)
In all other cases do attempt updates ...
*/
if ((table_being_updated->table->file->has_transactions() &&
- table_being_updated == update_tables) ||
- !some_table_is_not_transaction_safe(update_tables->next))
+ table_being_updated == update_tables) || !not_trans_safe)
ha_rollback_stmt(thd);
else if (do_update)
VOID(do_updates(true));
@@ -721,7 +711,6 @@ int multi_update::do_updates (bool from_send_error)
error = tmp_table->file->rnd_init(1);
if (error)
return error;
- bool not_trans_safe = some_table_is_not_transaction_safe(update_tables);
while (!(error=tmp_table->file->rnd_next(tmp_table->record[0])) &&
(!thd->killed || from_send_error || not_trans_safe))
{
@@ -756,7 +745,7 @@ bool multi_update::send_eof()
int error = do_updates(false); /* do_updates returns 0 if success */
/* reset used flags */
- update_tables->table->no_keyread=0;
+// update_tables->table->no_keyread=0;
if (error == -1) error = 0;
thd->proc_info="end";
if (error)
@@ -767,8 +756,7 @@ bool multi_update::send_eof()
was a non-transaction-safe table involved, since
modifications in it cannot be rolled back. */
- if (updated &&
- (!error || some_table_is_not_transaction_safe(update_tables)))
+ if (updated || not_trans_safe)
{
mysql_update_log.write(thd,thd->query,thd->query_length);
Query_log_event qinfo(thd, thd->query);
@@ -777,7 +765,7 @@ bool multi_update::send_eof()
is not used */
if (mysql_bin_log.is_open() && mysql_bin_log.write(&qinfo) &&
- !some_table_is_not_transaction_safe(update_tables))
+ !not_trans_safe)
error=1; /* Log write failed: roll back
the SQL statement */