summaryrefslogtreecommitdiff
path: root/sql/sql_insert.cc
diff options
context:
space:
mode:
authorChad MILLER <chad@mysql.com>2008-07-10 14:47:53 -0400
committerChad MILLER <chad@mysql.com>2008-07-10 14:47:53 -0400
commit6a6e77eeffc7dbd72888ef685fdb93fc2ae7aed6 (patch)
treed78d316822f255f22093dc0cc26ea8943b5f91d4 /sql/sql_insert.cc
parent5e0d806d276d27fef1a5dfcdca92f010836510ed (diff)
parent1aaa63aabaef8015c71fc6143b3062e197049707 (diff)
downloadmariadb-git-6a6e77eeffc7dbd72888ef685fdb93fc2ae7aed6.tar.gz
Merge chunk from trunk.
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r--sql/sql_insert.cc73
1 files changed, 49 insertions, 24 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index e00995e923a..67906b086d6 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -585,7 +585,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
bool log_on= (thd->options & OPTION_BIN_LOG) ||
(!(thd->security_ctx->master_access & SUPER_ACL));
#endif
- thr_lock_type lock_type = table_list->lock_type;
+ thr_lock_type lock_type;
Item *unused_conds= 0;
DBUG_ENTER("mysql_insert");
@@ -620,6 +620,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
}
+ lock_type= table_list->lock_type;
thd_proc_info(thd, "init");
thd->used_tables=0;
@@ -629,7 +630,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (mysql_prepare_insert(thd, table_list, table, fields, values,
update_fields, update_values, duplic, &unused_conds,
FALSE,
- (fields.elements || !value_count),
+ (fields.elements || !value_count ||
+ table_list->view != 0),
!ignore && (thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES))))
@@ -637,7 +639,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
/* mysql_prepare_insert set table_list->table if it was not set */
table= table_list->table;
- lock_type= table_list->lock_type;
context= &thd->lex->select_lex.context;
/*
@@ -2644,9 +2645,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 +2756,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 +2832,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 +2900,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 +2946,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 +2968,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 +3005,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 +3036,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 +3306,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 |