diff options
author | gluh@eagle.(none) <> | 2007-12-13 14:52:49 +0400 |
---|---|---|
committer | gluh@eagle.(none) <> | 2007-12-13 14:52:49 +0400 |
commit | e03959502978f9a7056b4adf6ba7c2a25f648b14 (patch) | |
tree | b870e5e7b713672711344eb2e5b585f3e2c48375 /sql/sql_insert.cc | |
parent | 9217f011361bf7c09f05692c409f52d553ce9690 (diff) | |
parent | 9f4f6acc53d1f9472def4a6f3fa650f6e72b1d6a (diff) | |
download | mariadb-git-e03959502978f9a7056b4adf6ba7c2a25f648b14.tar.gz |
Merge mysql.com:/home/gluh/MySQL/Merge/5.0
into mysql.com:/home/gluh/MySQL/Merge/5.0-opt
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7273fbf74e3..cf9e93b8518 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2644,9 +2644,9 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, enum_duplicates duplic, bool ignore_check_option_errors) :table_list(table_list_par), table(table_par), fields(fields_par), - last_insert_id(0), - insert_into_view(table_list_par && table_list_par->view != 0), - is_bulk_insert_mode(FALSE) + autoinc_value_of_last_inserted_row(0), + autoinc_value_of_first_inserted_row(0), + insert_into_view(table_list_par && table_list_par->view != 0) { bzero((char*) &info,sizeof(info)); info.handle_duplicates= duplic; @@ -2755,14 +2755,14 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) Is table which we are changing used somewhere in other parts of query */ - if (!(lex->current_select->options & OPTION_BUFFER_RESULT) && - unique_table(thd, table_list, table_list->next_global, 0)) + if (unique_table(thd, table_list, table_list->next_global, 0)) { /* Using same table for INSERT and SELECT */ lex->current_select->options|= OPTION_BUFFER_RESULT; lex->current_select->join->select_options|= OPTION_BUFFER_RESULT; } - else if (!thd->prelocked_mode) + else if (!(lex->current_select->options & OPTION_BUFFER_RESULT) && + !thd->prelocked_mode) { /* We must not yet prepare the result table if it is the same as one of the @@ -2831,11 +2831,8 @@ int select_insert::prepare2(void) { DBUG_ENTER("select_insert::prepare2"); if (thd->lex->current_select->options & OPTION_BUFFER_RESULT && - !thd->prelocked_mode && !is_bulk_insert_mode) - { + !thd->prelocked_mode) table->file->start_bulk_insert((ha_rows) 0); - is_bulk_insert_mode= TRUE; - } DBUG_RETURN(0); } @@ -2902,14 +2899,24 @@ bool select_insert::send_data(List<Item> &values) if (table->next_number_field) { /* + If no value has been autogenerated so far, we need to remember the + value we just saw, we may need to send it to client in the end. + */ + if (!thd->insert_id_used) + autoinc_value_of_last_inserted_row= table->next_number_field->val_int(); + /* Clear auto-increment field for the next record, if triggers are used we will clear it twice, but this should be cheap. */ table->next_number_field->reset(); - if (!last_insert_id && thd->insert_id_used) - last_insert_id= thd->last_insert_id; + if (!autoinc_value_of_last_inserted_row && thd->insert_id_used) + autoinc_value_of_last_inserted_row= thd->last_insert_id; } } + + if (thd->insert_id_used && !autoinc_value_of_first_inserted_row) + autoinc_value_of_first_inserted_row= thd->last_insert_id; + DBUG_RETURN(error); } @@ -2938,11 +2945,11 @@ bool select_insert::send_eof() { int error, error2; bool changed, transactional_table= table->file->has_transactions(); + ulonglong id; THD::killed_state killed_status= thd->killed; DBUG_ENTER("select_insert::send_eof"); error= (!thd->prelocked_mode) ? table->file->end_bulk_insert():0; - is_bulk_insert_mode= FALSE; table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); @@ -2960,8 +2967,17 @@ bool select_insert::send_eof() DBUG_ASSERT(transactional_table || !changed || thd->transaction.stmt.modified_non_trans_table); - if (last_insert_id) - thd->insert_id(info.copied ? last_insert_id : 0); // For binary log + // For binary log + if (autoinc_value_of_last_inserted_row) + { + if (info.copied) + thd->insert_id(autoinc_value_of_last_inserted_row); + else + { + autoinc_value_of_first_inserted_row= 0; + thd->insert_id(0); + } + } /* Write to binlog before commiting transaction */ if (mysql_bin_log.is_open()) { @@ -2988,7 +3004,9 @@ bool select_insert::send_eof() thd->row_count_func= info.copied + info.deleted + ((thd->client_capabilities & CLIENT_FOUND_ROWS) ? info.touched : info.updated); - ::send_ok(thd, (ulong) thd->row_count_func, last_insert_id, buff); + id= autoinc_value_of_first_inserted_row > 0 ? + autoinc_value_of_first_inserted_row : thd->last_insert_id; + ::send_ok(thd, (ulong) thd->row_count_func, id, buff); DBUG_RETURN(0); } @@ -3017,8 +3035,17 @@ void select_insert::abort() */ if (thd->transaction.stmt.modified_non_trans_table) { - if (last_insert_id) - thd->insert_id(last_insert_id); // For binary log + // For binary log + if (autoinc_value_of_last_inserted_row) + { + if (info.copied) + thd->insert_id(autoinc_value_of_last_inserted_row); + else + { + autoinc_value_of_first_inserted_row= 0; + thd->insert_id(0); + } + } if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, @@ -3278,10 +3305,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (info.handle_duplicates == DUP_UPDATE) table->file->extra(HA_EXTRA_INSERT_WITH_UPDATE); if (!thd->prelocked_mode) - { table->file->start_bulk_insert((ha_rows) 0); - is_bulk_insert_mode= TRUE; - } thd->abort_on_warning= (!info.ignore && (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | |