diff options
author | Sinisa@sinisa.nasamreza.org <> | 2002-01-16 22:45:47 +0200 |
---|---|---|
committer | Sinisa@sinisa.nasamreza.org <> | 2002-01-16 22:45:47 +0200 |
commit | d71bd75fcae533c2eda9020d0e51eb8b6183f7c4 (patch) | |
tree | 0d211c58a2586081354d31eb3906bcc060663385 /sql | |
parent | 74deec5a00ece82afad41de556e12e395962f304 (diff) | |
download | mariadb-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.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 124 | ||||
-rw-r--r-- | sql/sql_update.cc | 32 |
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 */ |